print("202510131420")
-- runTag 0-local 1-shopwegame 2-online
local runTag = 1
local singleTradeTimeoutSeconds = 60 -- 单次交易最多等待1分钟
local maxTradeTime = 600             -- 10分钟超时
local waitTradeTime = 600            -- 交易玩家不在线，等待上线时间10分钟
local tradeInterval = 5              -- 交易轮次间隔时间（秒）
local maxTradeRequestTime = 300      -- 最大交易请求等待时间（3分钟，玩家在线但不点同意交易）
local postOrderWaitSeconds = 5      -- 订单完成后再次检查等待时间（秒）

-- 获取库存配置
local OPTIMIZATION_CONFIG = {
    -- 缓存配置
    inventoryCacheDuration = 3,      -- 库存缓存时间（秒）
    -- 批量处理配置
    itemDelay = 0.15,               -- 单个物品延迟
}  

-- 统一状态文件：存储队列、确认记录、服务器状态
local STATE_FILE = "sync_state.json"

-- 不需要删除好友的用户ID列表配置
local EXEMPT_FRIEND_DELETE_USER_IDS = {
    9594941841, -- 测试用户 matye0829
    6161882101 -- 测试用户 lamb199303
}

-- 农场坐标配置
local FARM_CONFIG = {
    farm1Position = Vector3.new(34.62943649291992, 3.0000457763671875, 36.79352951049805),
    moveTimeout = 15,         -- 移动超时时间(秒)
    tradeDistance = 10,       -- 交易距离(单位:游戏单位)
}

-- 同步配置
local SYNC_CONFIG = {
    maxRetryInterval = 300, -- 最大重试间隔（5分钟）
    sequenceTimeout = 60,   -- 序列超时时间（秒）
    checkInterval = 10,     -- 检查间隔（秒）
}

-- 统一状态结构
local syncState = {
    queue = {},              -- 待处理队列
    isProcessing = false,    -- 是否正在处理
    lastProcessTime = 0,     -- 上次处理时间
    serverHealthy = true,    -- 服务器健康状态
    consecutiveFailures = 0, -- 连续失败次数
    recoveryMode = false,    -- 恢复模式
    lastRecoveryTime = 0,    -- 上次恢复时间
    activeOrder = nil,       -- 进行中的订单信息（用于故障恢复，最多1个）
    acks_done = {},          -- 订单完成的持久标记：orderMainId -> completedAt 时间戳
    loggedOrders = {},       -- 已打印日志的订单：orderMainId -> logType -> true
}

-- baseUrl 和 authSecret 用于订单查询与回调（硬编码）
local  baseUrl = "https://u7playearn.shopwegame.com/dev-api/play-earn/api/order"
if runTag == 1 then
    baseUrl = "https://player2earn.shopwegame.com/dev-api/play-earn/api/order"
elseif runTag == 2 then
    baseUrl = "https://player2earn.com/prod-api/play-earn/api/order"
end
local  authSecret = "8f9dbe334ca364eac2b18ca437fde25d"
local  lokiUrl = "https://lokipush.shopwegame.com/loki/api/v1/push"
-- 服务获取
local LocalPlayerName = game.Players.LocalPlayer.Name                                         -- 当前玩家名
local HttpService = game:GetService("HttpService")                                            -- 用于 HTTP 请求

local Players = game:GetService("Players")                                                    -- 玩家列表
local game_id = game.PlaceId * 3                                                              -- 交易接受参数使用
local LocalPlayer = game.Players.LocalPlayer                                                  -- 本地玩家
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GameEvents = ReplicatedStorage:WaitForChild("GameEvents")
-- 查找远程事件
local NotificationEvent = GameEvents:WaitForChild("Notification")
local GuiService = game:GetService("GuiService")                                              -- GUI服务
local VirtualInputManager = game:GetService("VirtualInputManager")                            -- 虚拟输入管理器

math.randomseed(os.time())

-- 说话功能：将日志 JSON 中的 message 字段作为聊天内容发送
local TextChatService = game:GetService("TextChatService")

local function getGeneralChannel()
    local ok, channel = pcall(function()
        if TextChatService.ChatVersion == Enum.ChatVersion.TextChatService then
            local channels = TextChatService:FindFirstChild("TextChannels")
            return channels and channels:FindFirstChild("RBXGeneral")
        end
        return nil
    end)
    if ok then return channel end
end

local function say(message)
    if type(message) ~= "string" or message == "" then return end
    -- 新版 TextChat（仅在开启新聊天系统时可用）
    local channel = getGeneralChannel()
    if channel then
        pcall(function()
            channel:SendAsync(string.sub(message, 1, 200))
        end)
    end
end

-- 给客服发送消息的API接口
local function sendCustomerServiceMessages(hintType)
    -- 构建URL，添加客服号标识 发送消息类型
    local url = string.format("%s/customer-service?authSecret=%s&robloxUserName=%s&type=messages&hintType=%s", 
                             baseUrl, authSecret, LocalPlayerName,hintType)
    
    local success, response = pcall(function()
        local result = httpGet(url)
        if not result then
            return nil, "HTTP request failed"
        end
        
        local result_d = HttpService:JSONDecode(result)
        if result_d.code == 200 then
            return result_d.data
        else
            return nil, "API returned error code: " .. tostring(result_d.code)
        end
    end)
    
    if not success then
        log("sendCustomerServiceMessages 请求失败: " .. tostring(response))
        return nil
    end
    
    return response
end
-- 交易提示消息（仅在指定的5个位置发送）
local function sendTradeHint(hintType)
    if hintType == 1 then
        say("请接受交易申请进行交易")
        -- say("Plz accept the trade request.")
    elseif hintType == 2 or hintType == 3 then
        say("请放置正确的物品进行交易")
        -- say("Plz put the correct items to trade")
    elseif hintType == 4 then
        say("请接受交易申请进行交易")
        -- say("Plz accept the trade request.")
    elseif hintType == 5 then
        say("交易失败，请再次在网站提交售卖请求")
        -- say("Trade failed, plz quit the server and sumbit the trading request in site again.")
    elseif hintType == 6 then
        say("收货开始交易")
        -- say("Trading start, plz accept the trading request and submit correct items.")
    elseif hintType == 7 then
        say("发货开始交易")
        -- say("Trading start, plz accept the trading request.")
    end
    -- sendCustomerServiceMessages(hintType)
end

-- 只上传这些类型的日志到 Loki（交易/订单相关）
local uploadLogTypes = {
    trade = true,
    trade_start = true,
    trade_success = true,
    trade_error = true,
    order_query = true,
    order_sync = true,
    progress = true,
    delete_friend = true
}

-- 安全的文件写入函数
-- mode: "append" 追加模式, "overwrite" 覆盖模式, 默认追加模式
local function safeWriteFile(filename, content, mode)
    mode = mode or "append"

    if mode == "append" then
        local success, err = pcall(function()
            appendfile(filename, content)
        end)

        if not success then
            local writeSuccess, writeErr = pcall(function()
                writefile(filename, content)
            end)

            if not writeSuccess then
                print("文件写入失败: " .. filename .. " - " .. tostring(writeErr))
            end
        end
    else -- overwrite mode
        local success, err = pcall(function()
            writefile(filename, content)
        end)

        if not success then
            local appendSuccess, appendErr = pcall(function()
                appendfile(filename, content)
            end)

            if not appendSuccess then
                print("文件写入失败: " .. filename .. " - " .. tostring(appendErr))
            end
        end
    end
end

-- 增强的日志上传函数（HttpGet 版本）
local function uploadToLoki(logMessage, metadata)
    -- metadata 可以包含: orderMainId, username, orderStatus, log_type 等

    -- 使用 Loki 标准格式
    local success, err = pcall(function()
        -- 获取当前时间戳（纳秒级）
        local timestamp = os.time() * 1000000000

        -- 构建 Loki 标准数据
        local lokiData = {
            streams = {
                {
                    stream = {
                        app = "roblox_gag",
                        log_type = metadata and metadata.log_type or "general",
                        username = metadata and metadata.username or LocalPlayerName,
                        orderMainId = metadata and metadata.orderMainId and tostring(metadata.orderMainId) or nil,
                        deliveryOrderId = metadata and metadata.deliveryOrderId and tostring(metadata.deliveryOrderId) or nil,
                        orderStatus = metadata and metadata.orderStatus and tostring(metadata.orderStatus) or nil,
                        makeStatus = metadata and metadata.makeStatus and tostring(metadata.makeStatus) or nil
                    },
                    values = {
                        { tostring(timestamp), logMessage }
                    }
                }
            }
        }

        -- 清理为 nil 的标签键
        for k, v in pairs(lokiData.streams[1].stream) do
            if v == nil then
                lokiData.streams[1].stream[k] = nil
            end
        end

        local response = request({
            Url = lokiUrl,
            Method = "POST",
            Headers = {
                ["Content-Type"] = "application/json"
            },
            Body = HttpService:JSONEncode(lokiData)
        })

        if response.Success then
            -- print("请求成功:", response.Body)
        else
            log(HttpService:JSONEncode({
                message = "上传日志请求失败",
                response = response,
            }))
        end
        return response
    end)

    if success then
        return -- Loki 标准格式上传成功，返回
    end
end

-- 日志函数优化
local log = function(s, metadata) -- 日志
    -- log(s, metadata): 记录到 log.txt；仅交易相关类型才上传到 Loki
    local logMessage = string.format("[%s] %s", os.date("%Y-%m-%d %H:%M:%S"), tostring(s))

    -- 记录到本地文件
    local success, err = pcall(function()
        appendfile("log.txt", logMessage .. "\n")
    end)
    if not success then
        writefile("log.txt", logMessage .. "\n")
    end
    -- 仅上传白名单内的交易日志
    if runTag ~= 0 and type(metadata) == "table" then
        local lt = metadata.log_type
        if lt and uploadLogTypes[lt] then
            uploadToLoki(tostring(s), metadata)
        end
    end
end

-- HTTP请求函数优化
local function httpGet(url)
    -- httpGet(url): 封装 game:HttpGet，失败记录日志。
    local success, result = pcall(function()
        return game:HttpGet(url, true)
    end)
    if success then
        return result
    else
        log("url请求失败：" .. url)
        return nil
    end
end

-- 将 totalDelivered 转换为发货订单的 items 结构
local function buildDeliveryItemsFromTotalDelivered(totalDelivered, orderStatus, receiveStatus)
    local items = {}
    for itemId, data in pairs(totalDelivered) do
        table.insert(items, {
            orderDeliverQuantity = data.quantity,  -- 实际发货数量
            tradeId = itemId,                      -- 物品ID
            deliveryOrderItemId = data.deliveryOrderItemId  -- 发货订单物品ID
        })
    end
    return items
end

-- 将 totalReceived 转换为服务器需要的 orderList 结构
local function buildOrderListFromTotalReceived(totalMap, orderStatus, receiveStatus)
    -- 输出为扁平结构：{ orderId, orderStatus, receiveStatus?, orderProductId?, quantity? }
    local list = {}
    if type(totalMap) ~= "table" then return list end
    for _, item in pairs(totalMap) do
        local entry = { orderId = item.orderId, orderStatus = orderStatus or 0 }
        -- 不用传receiveStatus
        -- if receiveStatus ~= nil then entry.receiveStatus = receiveStatus end
        if item.orderProductId ~= nil then entry.orderProductId = item.orderProductId end
        local q = tonumber(item.quantity)
        if q and q > 0 then 
            entry.quantity = q 
            table.insert(list, entry)
        end
       
    end
    return list
end


--// Anti idle 防止掉线函数
LocalPlayer.Idled:Connect(function()

	VirtualUser:CaptureController()
	VirtualUser:ClickButton2(Vector2.new())
end)

-- 删除好友接口
local function deleteFriend(robloxUserId)
    if not robloxUserId then
        log("deleteFriend 错误：缺少 robloxUserId 参数")
        return false
    end
    
    local url = string.format("http://45.77.227.112:8817/api/roblox/friends/del?delId=%s&userName=%s", tostring(robloxUserId), LocalPlayerName)
    local success, response = pcall(function()
        local result = httpGet(url)
        if not result then
            return nil, "HTTP request failed"
        end

        local result_d = HttpService:JSONDecode(result)
        if result_d.code == 200 then
            local data = result_d.data
            local logData = {
                message = "删除好友成功",
                robloxUserId = robloxUserId,
                data = data
            }
            log(HttpService:JSONEncode(logData), {
                log_type = "delete_friend",
                robloxUserId = robloxUserId,
                user = result_d.message,
            })
            return data -- 删除好友成功
        else
            return nil, "删除好友失败: " .. tostring(result_d.code)
        end
    end)

    if not success then
        log("deleteFriend 请求失败: " .. tostring(response))
        return false
    end

    if type(response) == "table" then
        return true
    else
        return false
    end
end

-- 监听玩家加入事件
-- game.Players.PlayerAdded:Connect(function(player)
--     -- 跳过自己
--     if player == game.Players.LocalPlayer then return end
    
--     -- 检查是否是好友
--     local isFriend = game.Players.LocalPlayer:IsFriendsWith(player.UserId)
--     if not isFriend then
--         -- 检查是否在豁免列表中
--         local shouldKick = true
--         for _, exemptId in ipairs(EXEMPT_FRIEND_DELETE_USER_IDS) do
--             if player.UserId == exemptId then
--                 shouldKick = false
--                 break
--             end
--         end
        
--         if shouldKick then
--             -- 先删除好友关系
--             deleteFriend(player.UserId)
--             -- 然后踢出房间
--             log(HttpService:JSONEncode({
--                 message = "非好友玩家被踢出房间",
--                 playerName = player.Name,
--                 playerId = player.UserId
--             }))
--         end
--     end
-- end)

-- 检查是否已打印过特定类型的日志
local function hasLoggedOrder(orderMainId, logType)
    if not syncState.loggedOrders[orderMainId] then
        return false
    end
    return syncState.loggedOrders[orderMainId][logType] == true
end

-- 标记订单日志已打印
local function markOrderLogged(orderMainId, logType)
    if not syncState.loggedOrders[orderMainId] then
        syncState.loggedOrders[orderMainId] = {}
    end
    syncState.loggedOrders[orderMainId][logType] = true
end


-- =============== 礼物赠送结果监听（参照 trade_grow_garden.lua） ===============
local giftTradeResult = nil
local giftTradeResultConn = nil

local function setupGiftResultListener()
    if giftTradeResultConn then
        giftTradeResultConn:Disconnect()
        giftTradeResultConn = nil
    end
    giftTradeResult = nil
    giftTradeResultConn = NotificationEvent.OnClientEvent:Connect(function(message)
        if type(message) ~= "string" then return end
        if message:find("Your target has declined your trade") then
            giftTradeResult = "declined"
        elseif message:find("Trade completed") then
            giftTradeResult = "completed"
        elseif message:find("Trade failed") then
            giftTradeResult = "failed"
        end
    end)
end

local function cleanupGiftResultListener()
    if giftTradeResultConn then
        giftTradeResultConn:Disconnect()
        giftTradeResultConn = nil
    end
    giftTradeResult = nil
end

local function waitForGiftResult(timeoutSeconds)
    timeoutSeconds = timeoutSeconds or singleTradeTimeoutSeconds
    log(HttpService:JSONEncode({
        message = "开始等待礼物赠送结果",
        timeoutSeconds = timeoutSeconds
    }))
    
    local startT = os.time()
    setupGiftResultListener()
    local result = "timeout"
    while os.time() - startT < timeoutSeconds do
        if giftTradeResult then
            result = giftTradeResult
            log(HttpService:JSONEncode({
                message = "收到礼物赠送结果",
                result = result,
                elapsedTime = os.time() - startT
            }))
            break
        end
        task.wait(0.5)
    end
    
    if result == "timeout" then
        log(HttpService:JSONEncode({
            message = "等待礼物赠送结果超时",
            timeoutSeconds = timeoutSeconds
        }))
    end
    
    cleanupGiftResultListener()
    return result
end

local function describePrompt(prompt)
    if not prompt then return { ok = false } end
    local info = {
        ok = true,
        name = tostring(prompt.Name),
        actionText = tostring(prompt.ActionText),
        holdDuration = tonumber(prompt.HoldDuration) or 0,
        enabled = (prompt.Enabled == nil) and true or (prompt.Enabled == true),
        requiresLineOfSight = (prompt.RequiresLineOfSight == true),
        maxActivationDistance = tonumber(prompt.MaxActivationDistance) or 0,
        parent = prompt.Parent and prompt.Parent:GetFullName() or "nil",
    }
    return info
end

-- 稳健触发 ProximityPrompt（带详细日志与重试）
local function tryActivatePrompt(prompt, context)
    context = context or ""
    local info = describePrompt(prompt)
    log(HttpService:JSONEncode({
        message = "准备触发赠送提示",
        context = context,
        prompt = info
    }))

    if not info.ok then
        log(HttpService:JSONEncode({ message = "Prompt 无效", context = context }))
        return false, "invalid_prompt"
    end

    -- 如果 ProximityPrompt 被禁用，先启用它
    if not prompt.Enabled then
        log(HttpService:JSONEncode({ 
            message = "ProximityPrompt 被禁用，尝试启用", 
            context = context 
        }))
        prompt.Enabled = true
        task.wait(0.2) -- 等待启用生效稍长一点
    end

    local holdPadding = 0.25
    local holdTime = tonumber(prompt.HoldDuration) or 0

    -- 尝试3：键盘事件（E键）
    local ok, err = pcall(function()
        VirtualInputManager:SendKeyEvent(true, Enum.KeyCode.E, false, game)
        task.wait(math.max(0.4, holdTime + holdPadding))
        VirtualInputManager:SendKeyEvent(false, Enum.KeyCode.E, false, game)
        task.wait(0.2) -- 给UI反应时间
    end)
    log(HttpService:JSONEncode({ message = "VIM E Key 触发", ok = ok, err = tostring(err) }))
    if ok then return true end

    return false, "all_methods_failed"
end


-- ================== 宠物相关辅助函数 ==================

-- 定义宠物名称关键词列表
local function getGuidePetNames()
    local ok, RS = pcall(function() return game:GetService("ReplicatedStorage") end)
    if not ok or not RS then return nil end
    local path = { "Modules", "GardenGuideModules", "DataModules", "PetData" }
    local node = RS
    for _, name in ipairs(path) do
        node = node:FindFirstChild(name)
        if not node then return nil end
    end
    if not node:IsA("ModuleScript") then return nil end
    local okReq, mod = pcall(function() return require(node) end)
    if not okReq or typeof(mod) ~= "table" then return nil end
    local dataTable = mod.Data or mod.Pets or mod.PetList
    if typeof(dataTable) ~= "table" then return nil end
    local names = {}
    for k,_ in pairs(dataTable) do
        if typeof(k) == "string" and #k > 0 then
            table.insert(names, k)
        end
    end
    if #names == 0 then return nil end
    table.sort(names, function(a,b) return a:lower() < b:lower() end)
    return names
end

local defaultPetNames = {"Bunny","Lab","Dog","Cat","Bird","Pet","Golden","Dragon","Fox","Bee","Butterfly"}
local petNames = getGuidePetNames() or defaultPetNames

-- 仅基于名称判断是否为宠物（用于订单里的字符串ID）
local function isPetName(name)
    if type(name) ~= "string" or name == "" then return false end
    -- 带重量标记视为宠物
    if name:match("%[%n?%d+%.%d+%sKG%]") or name:match("%[%n?%d+%sKG%]") then
        return true
    end
    local lname = string.lower(name)
    for _, kw in ipairs(petNames) do
        if lname:find(string.lower(tostring(kw)), 1, true) then
            return true
        end
    end
    return false
end

-- 判断物品是否为宠物（优先按分类，其次回退特征/名称）
local function isPet(tool)
    if not tool or not tool:IsA("Tool") then return false end

    local n = tool.Name or ""
    
    -- Grow a Garden 专用：包含重量信息即视为宠物（不要求年龄）
    local hasWeight = n:match("%[%d+%.%d+%sKG%]") ~= nil
    if hasWeight then
        return true
    end

    -- 名称中包含已知宠物关键词（最后兜底）
    local name = tool.Name or ""
    local petKeywords = petNames
    local lname = name:lower()
    for _, kw in ipairs(petKeywords) do
        if lname:find(kw:lower()) then 
            return true 
        end
    end

    return false
end

-- 解析名称中的重量/年龄
local function parseWeightAge(name)
    local w = tonumber((name or ""):match("%[(%d+%.%d+)%sKG%]"))
    local a = tonumber((name or ""):match("%[Age%s(%d+)%]"))
    return w, a
end

-- 获取目标玩家函数
local function getTarget(targetPlayerName)
    -- 尝试查找指定的目标玩家
    local target = Players:FindFirstChild(targetPlayerName)
    return target
end

-- 移动到目标玩家附近的函数
local function moveNear(target, tradeDistance)
    tradeDistance = tradeDistance or 10
    -- 检查本地玩家和目标玩家及其角色是否存在
    if not (LocalPlayer.Character and target and target.Character) then return false end
    
    -- 获取本地玩家和目标玩家的人形组件和根部件
    local myHum = LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
    local root = target.Character:FindFirstChild("HumanoidRootPart")
    -- 如果缺少必要组件则返回失败
    if not (myHum and root) then return false end
    
    -- 移动到目标玩家位置
    myHum:MoveTo(root.Position)
    
    -- 等待直到接近目标玩家或超时
    local startTime = tick()
    local timeout = 15 -- 15秒超时
    
    while tick() - startTime < timeout do
        -- 获取本地玩家的根部件
        local meRoot = LocalPlayer.Character:FindFirstChild("HumanoidRootPart")
        -- 检查距离是否在交易范围内
        if meRoot then
            local distance = (meRoot.Position - root.Position).Magnitude
            -- 检查是否在交易范围内
            if distance <= tradeDistance then
                -- 接近后额外等待1秒确保UI完全加载
                task.wait(1)
                return true  -- 成功接近
            end
        end
        task.wait(0.2)  -- 等待0.2秒再次检查
    end
    return false  -- 超时未成功接近
end

-- 检测背包和手中是否有指定宠物的函数
local function findPetInBackpack(targetPetName)
    local foundPets = {}

    -- 1) 手中
    local character = LocalPlayer.Character
    if character then
        local equippedTool = character:FindFirstChildOfClass("Tool")
        if isPet(equippedTool) and equippedTool.Name:find(targetPetName) then
            table.insert(foundPets, equippedTool)
        end
    end

    -- 2) 背包
    local backpack = LocalPlayer:FindFirstChild("Backpack")
    if not backpack then 
        return nil 
    end
    for _, tool in ipairs(backpack:GetChildren()) do
        if isPet(tool) and tool.Name:find(targetPetName) then
            table.insert(foundPets, tool)
        end
    end

    if #foundPets > 0 then
        if #foundPets > 1 then
            table.sort(foundPets, function(a, b)
                local weightA = tonumber(a.Name:match("%[(%d+%.%d+) KG%]")) or 0
                local weightB = tonumber(b.Name:match("%[(%d+%.%d+) KG%]")) or 0
                return weightA > weightB
            end)
        end
        return foundPets[1]
    else
        return nil
    end
end

-- 按名字整理背包中宠物数据的函数
local function organizePetsInBackpack()
    -- 使用 pcall 保护整个函数，避免任何 nil 值调用
    local success, petData, totalPets, organizedList = pcall(function()
        log(HttpService:JSONEncode({
            message = "开始整理背包中的宠物数据"
        }))
        
        local petData = {}
        local totalPets = 0
        
        -- 1) 检查手中的宠物
        local character = LocalPlayer.Character
        if character then
            local equippedTool = character:FindFirstChildOfClass("Tool")
            if equippedTool and isPet(equippedTool) then
                local petName = equippedTool.Name
                local weight, age = parseWeightAge(petName)
                
                if not petData[petName] then
                    petData[petName] = {
                        name = petName,
                        weight = weight,
                        age = age,
                        count = 0,
                        locations = {}
                    }
                end
                
                petData[petName].count = petData[petName].count + 1
                table.insert(petData[petName].locations, "手中")
                totalPets = totalPets + 1
                
                log(HttpService:JSONEncode({
                    message = "手中发现宠物",
                    petName = petName,
                    weight = weight,
                    age = age
                }))
            end
        end
        
        -- 2) 检查背包中的宠物
        local backpack = LocalPlayer:FindFirstChild("Backpack")
        if not backpack then 
            log(HttpService:JSONEncode({
                message = "背包不存在"
            }))
            return petData, totalPets
        end
        
        for _, tool in ipairs(backpack:GetChildren()) do
            -- 检查是否为工具类物品
            if tool:IsA("Tool") then
                if isPet(tool) then
                    local petName = tool.Name
                    local weight, age = parseWeightAge(petName)
                    
                    if not petData[petName] then
                        petData[petName] = {
                            name = petName,
                            weight = weight,
                            age = age,
                            count = 0,
                            locations = {}
                        }
                    end
                    
                    petData[petName].count = petData[petName].count + 1
                    table.insert(petData[petName].locations, "背包")
                    totalPets = totalPets + 1
                    
                    log(HttpService:JSONEncode({
                        message = "背包中找到宠物",
                        petName = petName,
                        weight = weight,
                        age = age
                    }))
                end
            end
        end
        
        -- 3) 整理和输出结果
        log(HttpService:JSONEncode({
            message = "宠物数据整理完成",
            totalPets = totalPets,
            uniquePets = 0
        }))
        
        local organizedList = {}
        for petName, data in pairs(petData) do
            table.insert(organizedList, {
                name = data.name,
                weight = data.weight,
                age = data.age,
                count = data.count,
                locations = table.concat(data.locations, ", ")
            })
            
            log(HttpService:JSONEncode({
                message = "宠物统计",
                petName = data.name,
                weight = data.weight,
                age = data.age,
                count = data.count,
                locations = table.concat(data.locations, ", ")
            }))
        end
        
        -- 按名字排序
        table.sort(organizedList, function(a, b)
            return a.name < b.name
        end)
        
        log(HttpService:JSONEncode({
            message = "背包宠物数据整理完成",
            totalPets = totalPets,
            uniquePets = #organizedList,
            petList = organizedList
        }))
        
        return petData, totalPets, organizedList
    end)
    
    if not success then
        -- 如果整个函数执行失败，记录错误并返回空结果
        log(HttpService:JSONEncode({
            message = "organizePetsInBackpack 执行失败",
            error = tostring(petData)
        }))
        return {}, 0, {}
    end
    
    return petData, totalPets, organizedList
end

-- 检查目标宠物是否在订单列表中的函数
local function checkPetInOrderList(petName, orderList)
    if not petName or not orderList or type(orderList) ~= "table" then
        log(HttpService:JSONEncode({
            message = "检查宠物参数无效",
            petName = petName,
            orderListType = type(orderList)
        }))
        return false, nil
    end
    
    log(HttpService:JSONEncode({
        message = "开始检查宠物是否在订单列表中",
        targetPetName = petName,
        orderListCount = #orderList
    }))
    
    -- 遍历订单列表检查每个物品
    for _, order in ipairs(orderList) do
        if order.product and order.product.tradeId then
            local orderItemName = order.product.tradeId
            
            log(HttpService:JSONEncode({
                message = "检查订单物品",
                orderItemName = orderItemName,
                targetPetName = petName,
                orderId = order.orderId
            }))
            
            -- 检查宠物名称是否匹配（支持部分匹配）
            if orderItemName:find(petName) or petName:find(orderItemName) then
                log(HttpService:JSONEncode({
                    message = "找到匹配的宠物订单",
                    targetPetName = petName,
                    orderItemName = orderItemName,
                    orderId = order.orderId,
                    quantity = order.product.quantity
                }))
                
                return true, {
                    orderId = order.orderId,
                    orderProductId = order.product.orderProductId,
                    tradeId = order.product.tradeId,
                    quantity = order.product.quantity,
                    order = order
                }
            end
        end
    end
    
    log(HttpService:JSONEncode({
        message = "未找到匹配的宠物订单",
        targetPetName = petName
    }))
    
    return false, nil
end

-- 智能装备宠物的函数
local function smartEquipPet(pet)
    if not pet then return false end
    
    -- 方法1：尝试直接装备宠物到角色
    local success = pcall(function()
        pet.Parent = LocalPlayer.Character
    end)
    
    if success then
        task.wait(0.5)  -- 等待装备完成
        local character = LocalPlayer.Character
        if character then
            local equippedTool = character:FindFirstChildOfClass("Tool")
            if equippedTool and equippedTool.Name == pet.Name then
                return true
            end
        end
    end
    
    return false
end

-- 选中宠物
local function selectPet(pet)
    if not pet then 
        return false 
    end
    
    -- 检查宠物是否已经在手中
    local character = LocalPlayer.Character
    if character then
        local equippedTool = character:FindFirstChildOfClass("Tool")
        if equippedTool and equippedTool.Name == pet.Name then
            return true
        end
        
        -- 如果手中有其他宠物，先卸下
        if equippedTool and isPet(equippedTool) then
            log(HttpService:JSONEncode({
                message = "卸下手中宠物",
                petName = equippedTool.Name
            }))
            local ok = pcall(function()
                equippedTool.Parent = LocalPlayer.Backpack
            end)
            if ok then
                task.wait(0.3) -- 等待卸下完成
            end
        end
    end
    
    -- 使用智能装备方法
    return smartEquipPet(pet)
end

-- 清理所有选中状态的函数
local function clearAllSelections(targetPetName)
    local clearedCount = 0
    
    -- 1) 将手中宠物放回背包，避免二次选择叠加
    local character = LocalPlayer.Character
    if character then
        local equippedTool = character:FindFirstChildOfClass("Tool")
        if equippedTool and isPet(equippedTool) and equippedTool.Name:find(targetPetName) then
            local ok = pcall(function()
                equippedTool.Parent = LocalPlayer.Backpack
            end)
            if ok then
                clearedCount = clearedCount + 1
            end
        end
    end

    -- 2) 清理背包中的所有宠物选中状态
    local backpack = LocalPlayer:FindFirstChild("Backpack")
    if not backpack then 
        return false 
    end
    for _, tool in ipairs(backpack:GetChildren()) do
        if isPet(tool) and tool.Name:find(targetPetName) then
            -- 通过重新设置父级来取消选中状态
            local ok = pcall(function()
                tool.Parent = backpack
            end)
            if ok then
                clearedCount = clearedCount + 1
            end
        end
    end
    
    if clearedCount > 0 then
        task.wait(0.5)  -- 等待清理完成
        return true
    else
        return true
    end
end

-- 检查目标玩家手中的宠物是否符合要求
local function checkTargetPlayerPet(targetPlayerName, orderList)
    local orderDetail = nil
    local target = getTarget(targetPlayerName)
    if not target then 
        return false, orderDetail
    end
    
    -- 检查目标玩家角色是否存在
    local character = target.Character
    if not character then
        return false, orderDetail  
    end
    
    -- 检查目标玩家手中的工具
    local equippedTool = character:FindFirstChildOfClass("Tool")
    if not equippedTool then
        return false,orderDetail                 
    end
    -- 检查是否为宠物
    if not isPet(equippedTool) then
        return false, orderDetail
    end
    
    -- 检查宠物是否在订单列表中
    local isInOrder, orderDetails = checkPetInOrderList(equippedTool.Name, orderList) 
    
    -- 如果找到匹配的订单，更新orderDetail
    if isInOrder and orderDetails then
        orderDetail = orderDetails
    end

        
    -- 检查是否包含目标宠物名称关键词
    if not isInOrder then
        return false, orderDetail
    end

    
    -- 如果不在订单中，返回false
    if not isInOrder then
        return false, orderDetail                     
    end
    
    return true, orderDetail
end

-- 触发按钮所有连接事件的函数
local function fireAllConnections(btn)
    local any = false  -- 标记是否有任何事件被触发
    
    -- 内部函数：触发单个信号连接
    local function fire(signal)
        -- 如果信号不存在则返回
        if not signal then return end
        
        -- 使用pcall防止错误
        pcall(function()
            -- 检查getconnections函数是否可用
            if typeof(getconnections) == "function" then
                -- 获取所有连接
                for _, c in ipairs(getconnections(signal)) do
                    pcall(function()
                        -- 尝试调用连接函数或触发事件
                        if c.Function then c.Function() elseif c.Fire then c:Fire() end
                        any = true  -- 标记已触发事件
                    end)
                end
            end
        end)
    end
    
    -- 尝试触发按钮的各种事件
    fire(btn.MouseButton1Click)  -- 鼠标左键点击事件
    
    return any  -- 返回是否有事件被触发
end

-- 获取礼物通知界面中的接受和拒绝按钮
local function getButtons()
    -- 获取玩家GUI
    local pg = LocalPlayer:FindFirstChild("PlayerGui")
    if not pg then return nil, nil end
    
    -- 查找礼物通知界面
    local gui = pg:FindFirstChild("Gift_Notification")
    if not gui then return nil, nil end
    
    -- 通过多层嵌套查找接受和拒绝按钮
    local f1 = gui:FindFirstChild("Frame"); if not f1 then return nil,nil end
    local g2 = f1:FindFirstChild("Gift_Notification"); if not g2 then return nil,nil end
    local holder = g2:FindFirstChild("Holder"); if not holder then return nil,nil end
    local f2 = holder:FindFirstChild("Frame"); if not f2 then return nil,nil end
    
    -- 返回接受和拒绝按钮
    return f2:FindFirstChild("Accept"), f2:FindFirstChild("Decline")
end

-- 点击按钮的函数，多种方法尝试点击按钮
local function clickButton(btn)
    -- 如果按钮不存在则返回失败
    if not btn then return false end
    -- 触发所有连接事件（不提前返回，后续仍尝试 VIM 点击以确保生效）
    fireAllConnections(btn)

    -- 方法1: 设置焦点 + 发送按键事件（参考代码方法）
    pcall(function()
        local guiService = GuiService
        local vim = VirtualInputManager
        if guiService and vim and typeof(vim.SendKeyEvent) == "function" then
            guiService.SelectedObject = btn
            task.wait(0.1) -- 等待焦点设置完成
            vim:SendKeyEvent(true, Enum.KeyCode.Return, false, game)
            task.wait(0.05)
            vim:SendKeyEvent(false, Enum.KeyCode.Return, false, game)
        end
        task.wait(0.1)
        guiService.SelectedObject = nil
    end)

    return true  -- 默认返回成功
end

-- 自动接受礼物的函数
local function autoAccept()
    -- 获取接受按钮
    local accept = select(1, getButtons())
    if accept then clickButton(accept) end
end

-- 自动拒绝礼物的函数
local function autoDecline()
    local decline = select(2, getButtons())
    if decline then clickButton(decline) end
end

-- 移动到1号农场初始位置的函数（使用配置坐标）
local function moveToFarm1()
    -- 检查本地玩家和角色是否存在
    if not LocalPlayer or not LocalPlayer.Character then
        log(HttpService:JSONEncode({
            message = "本地玩家或角色不存在"
        }))
        return false
    end
    
    -- 获取人形组件
    local myHum = LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
    if not myHum then
        log(HttpService:JSONEncode({
            message = "角色没有人形组件"
        }))
        return false
    end
    
    -- 使用配置中的农场坐标
    local farm1Position = FARM_CONFIG.farm1Position
    
    log(HttpService:JSONEncode({
        message = "从0号农场移动到1号农场",
        targetPosition = tostring(farm1Position)
    }))
    myHum:MoveTo(farm1Position)
    
    -- 等待直到到达1号农场或超时
    local startTime = tick()
    local timeout = FARM_CONFIG.moveTimeout -- 使用配置中的超时时间
    
    log(HttpService:JSONEncode({
        message = "1号农场目标坐标",
        position = tostring(farm1Position)
    }))
    
    while tick() - startTime < timeout do
        local rootPart = LocalPlayer.Character:FindFirstChild("HumanoidRootPart")
        if rootPart then
            local distance = (rootPart.Position - farm1Position).Magnitude
            -- 记录当前位置信息
            if tick() - startTime < 0.5 then
                log(HttpService:JSONEncode({
                    message = "距离1号农场目标位置",
                    distance = math.floor(distance),
                    currentPosition = tostring(rootPart.Position)
                }))
            end
        
            if distance <= FARM_CONFIG.tradeDistance then
                log(HttpService:JSONEncode({
                    message = "已到达1号农场",
                    distance = math.floor(distance),
                    currentPosition = tostring(rootPart.Position)
                }))
                return true
            end
        end
        task.wait(0.2)
    end
    
    log(HttpService:JSONEncode({
        message = "移动到1号农场超时"
    }))
    return false
end

-- 收货订单获取
local function getReceivingOrder()
    if runTag == 0 then
        return {
            orderMainId = "1960614033613475841",                    -- 主订单ID
            robloxUserName = "matye0829",                         -- 卖家roblox用户名
            robloxUserId = 9594941841,                              -- 卖家roblox用户id
            inventoryAccountName = "pssmurf0078",                   -- 库存号roblox用户名
            orderList = {                                           -- 订单列表
                {
                    orderId = "1960614033747693560",                -- 订单ID
                    product = {
                        tradeId = "Bunny",                            -- 物品ID
                        orderProductId = "1960614033936437251",     -- 订单物品ID
                        quantity = 1                                -- 物品数量
                    }
                },
                {
                    orderId = "1960614033747693561",                -- 订单ID
                    product = {
                        tradeId = "Dog",                           -- 物品ID
                        orderProductId = "1960614033936437252",     -- 订单物品ID
                        quantity = 1                                -- 物品数量
                    }
                },
            }
        }
    end

    local url = string.format("%s/query?authSecret=%s&robloxUserName=%s", baseUrl, authSecret, LocalPlayerName)
    local success, response = pcall(function()
        local result = httpGet(url)
        if not result then
            return nil, "HTTP request failed"
        end

        local result_d = HttpService:JSONDecode(result)
        if result_d.code == 200 then
            local data = result_d.data
            local logData = {
                message = "收货订单查询",
                data = data
            }
            log(HttpService:JSONEncode(logData), {
                log_type = "order_query",
                orderMainId = data.orderMainId,
            })
            
            -- 强化去重逻辑：多重检查机制
            if data.orderMainId then
                local orderMainId = tostring(data.orderMainId)
                
                -- 1. 检查 acks_done（持久完成标记）
                if type(syncState) == "table" and syncState.acks_done and syncState.acks_done[orderMainId] then
                    local doneAt = syncState.acks_done[orderMainId]
                    -- 只打印一次日志
                    if not hasLoggedOrder(orderMainId, "acks_done") then
                        log(HttpService:JSONEncode({
                            message = "订单已完成(acks_done)，忽略返回",
                            orderMainId = data.orderMainId,
                            doneAt = doneAt,
                            timeSinceDone = os.time() - doneAt
                        }))
                        markOrderLogged(orderMainId, "acks_done")
                    end
                    return nil, "order already done by ack"
                end
                
                -- 2. 检查 activeOrder（进行中的订单）
                if type(syncState) == "table" and syncState.activeOrder and 
                   syncState.activeOrder.orderMainId == data.orderMainId then
                    -- 只打印一次日志
                    if not hasLoggedOrder(orderMainId, "activeOrder") then
                        log(HttpService:JSONEncode({
                            message = "订单正在进行中(activeOrder)，忽略返回",
                            orderMainId = data.orderMainId,
                            activeOrderStatus = syncState.activeOrder.orderStatus,
                            lastUpdateTime = syncState.activeOrder.lastUpdateTime
                        }))
                        markOrderLogged(orderMainId, "activeOrder")
                    end
                    return nil, "order already active"
                end
                
                -- 3. 检查队列中是否有相同订单的完成状态
                if type(syncState) == "table" and syncState.queue then
                    for _, task in ipairs(syncState.queue) do
                        if task.data and task.data.orderMainId == data.orderMainId and 
                           task.data.orderStatus == 4 then
                            -- 只打印一次日志
                            if not hasLoggedOrder(orderMainId, "queue_completed") then
                                log(HttpService:JSONEncode({
                                    message = "订单已在队列中完成，忽略返回",
                                    orderMainId = data.orderMainId,
                                    taskId = task.id,
                                    orderStatus = task.data.orderStatus,
                                    receiveStatus = task.data.receiveStatus
                                }))
                                markOrderLogged(orderMainId, "queue_completed")
                            end
                            return nil, "order already completed in queue"
                        end
                    end
                end
            end
            return data -- 直接返回完整的主订单数据
        else
            return nil, "API returned error code: " .. tostring(result_d.code)
        end
    end)

    if not success then
        log("getReceivingOrder 请求失败: " .. tostring(response))
        return {}
    end

    if type(response) == "table" then
        return response
    else
        return {}
    end
end

-- 发货订单获取优化 - 支持多物品
local function getDeliveryOrder()
    if runTag == 0 then
        return {
            deliveryOrderId = "1976918433051009025",           -- 发货订单ID
            robloxUserName = "matye0829",                     -- 买家roblox用户名
            robloxUserId = 9594941841,                          -- 买家roblox用户id
            createTime = 1760169058466,                          -- 创建时间
            items = {                                           -- 物品列表
                {
                    deliveryOrderItemId = "1976918433084563457", -- 发货订单物品ID
                    tradeId = "Bunny",                            -- 物品ID
                    orderQuantity = 1                           -- 物品数量
                },
                {
                    deliveryOrderItemId = "1976918433084563458", -- 发货订单物品ID
                    tradeId = "Dog",                            -- 物品ID
                    orderQuantity = 1                           -- 物品数量
                },
                -- {
                --     deliveryOrderItemId = "1976918433084563459", -- 发货订单物品ID
                --     tradeId = "Shiba Inu",                            -- 物品ID
                --     orderQuantity = 1                           -- 物品数量
                -- }
            }
        }
    end

    local url = string.format("%s/queryDeliveryOrder?authSecret=%s&robloxUserName=%s", baseUrl, authSecret, LocalPlayerName)
    local success, response = pcall(function()
        local result = httpGet(url)
        if not result then
            return nil, "HTTP request failed"
        end

        local result_d = HttpService:JSONDecode(result)
        if result_d.code == 200 then
            local data = result_d.data
            local logData = {
                message = "发货订单查询",
                data = data
            }
            log(HttpService:JSONEncode(logData), {
                log_type = "order_query",
                deliveryOrderId = data.deliveryOrderId,
            })
            
            -- 强化去重逻辑：多重检查机制
            if data.deliveryOrderId then
                local deliveryOrderId = tostring(data.deliveryOrderId)
                
                -- 1. 检查 acks_done（持久完成标记）
                if type(syncState) == "table" and syncState.acks_done and syncState.acks_done[deliveryOrderId] then
                    local doneAt = syncState.acks_done[deliveryOrderId]
                    log(HttpService:JSONEncode({
                        message = "订单已完成(acks_done)，忽略返回",
                        deliveryOrderId = data.deliveryOrderId,
                        doneAt = doneAt,
                        timeSinceDone = os.time() - doneAt
                    }))
                    return nil, "order already done by ack"
                end
                
                -- 2. 检查 activeOrder（进行中的订单）
                if type(syncState) == "table" and syncState.activeOrder and 
                   syncState.activeOrder.deliveryOrderId == data.deliveryOrderId then
                    log(HttpService:JSONEncode({
                        message = "订单正在进行中(activeOrder)，忽略返回",
                        deliveryOrderId = data.deliveryOrderId,
                        activeOrderStatus = syncState.activeOrder.makeStatus,
                        lastUpdateTime = syncState.activeOrder.lastUpdateTime
                    }))
                    return nil, "order already active"
                end
                
                -- 3. 检查队列中是否有相同订单的完成状态
                if type(syncState) == "table" and syncState.queue then
                    for _, task in ipairs(syncState.queue) do
                        if task.data and task.data.deliveryOrderId == data.deliveryOrderId and 
                           task.data.makeStatus == 2 then
                            log(HttpService:JSONEncode({
                                message = "订单已在队列中完成，忽略返回",
                                deliveryOrderId = data.deliveryOrderId,
                                taskId = task.id,
                                makeStatus = task.data.makeStatus,
                                receiveStatus = task.data.receiveStatus
                            }))
                            return nil, "order already completed in queue"
                        end
                    end
                end
            end
            return data -- 直接返回完整的主订单数据
        else
            return nil, "API returned error code: " .. tostring(result_d.code)
        end
    end)

    if not success then
        log("getDeliveryOrder 请求失败: " .. tostring(response))
        return {}
    end

    if type(response) == "table" then
        return response
    else
        return {}
    end
end

-- 检查玩家是否在线且在同一房间，并且已经加载完成
local function isUserOnlineAndReady(user)
    local p = Players:FindFirstChild(user)
    if not p then
        return false, "玩家不在线"
    end

    -- 检查玩家是否在同一服务器/房间
    if not p.Parent then
        return false, "玩家不在当前房间"
    end

    -- 检查玩家是否已经加载完成（有Character）
    if not p.Character then
        return false, "玩家角色未加载完成"
    end

    -- 检查玩家角色是否有必要的组件（确保完全加载）
    local character = p.Character
    if not character:FindFirstChild("Humanoid") then
        return false, "玩家角色Humanoid未加载"
    end

    if not character:FindFirstChild("HumanoidRootPart") then
        return false, "玩家角色HumanoidRootPart未加载"
    end

    -- 检查玩家是否在有效位置（避免在加载中或异常状态）
    local humanoidRootPart = character.HumanoidRootPart
    if not humanoidRootPart or not humanoidRootPart.Position then
        return false, "玩家位置信息无效"
    end

    return true, "玩家在线且已准备就绪"
end

-- 检查玩家是否在线且在同一房间（简化版本，用于快速检查）
local function isUserInSameRoom(user)
    local p = Players:FindFirstChild(user)
    if not p then
        return false, "玩家不在线"
    end

    -- 检查玩家是否在同一服务器/房间
    if not p.Parent then
        return false, "玩家不在当前房间"
    end

    return true, "玩家在同一房间"
end

-- 等待玩家完全加载完成（带超时）
local function waitForUserReady(user, maxWaitSeconds)
    maxWaitSeconds = maxWaitSeconds or 30
    local deadline = os.time() + maxWaitSeconds

    while os.time() < deadline do
        local isReady, reason = isUserOnlineAndReady(user)
        if isReady then
            return true, "玩家已准备就绪"
        end

        -- 每2秒检查一次
        task.wait(2)
    end

    return false, "等待玩家加载超时"
end

-- 从快照读取某个物品数量
local function getItemNumFromSnapshot(invSnapshot, itemId)
    if type(invSnapshot) ~= "table" then return 0 end
    if type(itemId) ~= "string" or itemId == "" then return 0 end

    -- Grow a Garden 背包快照为按完整名称聚合（含重量/年龄），例如：
    --   "Bunny [11.85 KG] [Age 80]" => { count = 1, ... }
    -- 这里按名称包含关系对 itemId 做模糊统计：如 itemId="Bunny" 时统计所有包含 "Bunny" 的条目的 count 之和
    local total = 0
    local needle = string.lower(itemId)
    for name, data in pairs(invSnapshot) do
        if type(name) == "string" and type(data) == "table" then
            local lname = string.lower(name)
            if string.find(lname, needle, 1, true) then
                local q = tonumber(data.count) or 0
                total = total + q
            end
        end
    end
    return total
end

-- 保留简化读取接口（单次直接拉取，不建议在循环中使用）
local function getItemNum(itemId)
    local inv = select(1, organizePetsInBackpack())
    return getItemNumFromSnapshot(inv, itemId)
end


-- ================= 保证送达：本地持久化队列 =================
-- 只使用一个文件存储所有状态，减少IO操作
-- 主要功能：请求入队、自动重试、指数退避、有序同步

-- 安全读取文件内容
local function safeRead(path)
    local ok, res = pcall(function() return readfile(path) end)
    if ok and res and #res > 0 then return res end
    return ""
end

-- 加载统一状态
local function loadState()
    local s = safeRead(STATE_FILE)
    if s == "" then return syncState end
    local ok, t = pcall(function() return HttpService:JSONDecode(s) end)
    return ok and t or syncState
end

-- 保存统一状态
local function saveState()
    if runTag == 0 then
        return 
    end
    safeWriteFile(STATE_FILE, HttpService:JSONEncode(syncState), "overwrite")
end

-- 检查服务器健康状态
local function checkServerHealth()
    local testUrl = string.format("%s/query?authSecret=%s&robloxUserName=%s", baseUrl, authSecret, LocalPlayerName)
    local result = httpGet(testUrl)
    return result ~= nil
end

-- 更新服务器健康状态
local function updateServerHealth(isHealthy)
    local now = os.time()

    if isHealthy then
        if not syncState.serverHealthy then
            -- 服务器从故障状态恢复
            syncState.lastRecoveryTime = now
            syncState.recoveryMode = true
            log(HttpService:JSONEncode({
                message = "服务器恢复，进入快速同步模式",
                recoveryTime = now,
                consecutiveFailures = syncState.consecutiveFailures
            }))
        end
        syncState.consecutiveFailures = 0
    else
        syncState.consecutiveFailures = syncState.consecutiveFailures + 1
        if syncState.serverHealthy then
            log(HttpService:JSONEncode({
                message = "服务器故障，进入重试模式",
                consecutiveFailures = syncState.consecutiveFailures
            }))
        end
    end

    syncState.serverHealthy = isHealthy

    -- 如果恢复模式超过10分钟，退出恢复模式
    if syncState.recoveryMode and (now - syncState.lastRecoveryTime) > 600 then
        syncState.recoveryMode = false
        log(HttpService:JSONEncode({
            message = "退出快速同步模式，恢复正常处理间隔"
        }))
    end
end

-- 检查是否可以开始下一个同步
local function canStartNextSync()
    local now = os.time()

    -- 检查序列超时 - 优先检查，避免长时间阻塞
    if syncState.lastProcessTime > 0 and (now - syncState.lastProcessTime) > SYNC_CONFIG.sequenceTimeout then
        log(HttpService:JSONEncode({
            message = "序列超时，重置处理状态",
            lastProcessTime = syncState.lastProcessTime,
            timeout = SYNC_CONFIG.sequenceTimeout,
            isProcessing = syncState.isProcessing
        }))
        syncState.isProcessing = false
    end

    -- 如果正在处理，不能开始新的同步
    if syncState.isProcessing then
        return false
    end

    -- 如果服务器不健康，不能开始同步
    if not syncState.serverHealthy then
        return false
    end

    return true
end

-- 计算重试间隔
local function getRetryInterval(retryCount)
    local base = math.min(SYNC_CONFIG.maxRetryInterval, 2 ^ math.min(retryCount or 0, 6))

    -- 如果服务器健康，使用较短的重试间隔
    if syncState.serverHealthy then
        base = math.min(base, 5) -- 健康时最多5秒
    end

    -- 如果处于恢复模式，使用更短的重试间隔
    if syncState.recoveryMode then
        base = math.min(base, 2) -- 恢复模式最多2秒
    end

    return math.max(1, base)
end

-- 处理队列中的待发送请求
local function flushQueue()
    if runTag == 0 then
        return
    end
    local now = os.time()

    -- 检查服务器健康状态
    local isServerHealthy = checkServerHealth()
    updateServerHealth(isServerHealthy)

    -- 如果没有待处理任务，直接返回
    if #syncState.queue == 0 then
        return
    end
    
    if not canStartNextSync() then
        log(HttpService:JSONEncode({
            message = "无法开始同步",
            queueSize = #syncState.queue,
            isProcessing = syncState.isProcessing,
            serverHealthy = syncState.serverHealthy,
            lastProcessTime = syncState.lastProcessTime,
            timeSinceLastProcess = now - syncState.lastProcessTime
        }))
        return
    end

    -- 按创建时间排序，确保有序同步
    table.sort(syncState.queue, function(a, b)
        return (a.createdAt or 0) < (b.createdAt or 0)
    end)

    -- 处理第一个任务（最旧的）
    local task = syncState.queue[1]
    syncState.isProcessing = true
    syncState.lastProcessTime = now
    
    -- 使用 pcall 确保异常时也能重置状态
    local success, result = pcall(function()
        -- 根据订单类型选择不同的同步接口
        local url
        if task.data and task.data.deliveryOrderId then
            -- 发货订单使用 syncDeliveryOrder 接口
            url = string.format("%s/syncDeliveryOrder", baseUrl)
        else
            -- 收货订单使用 sync 接口
            url = string.format("%s/sync", baseUrl)
        end
        
        local ok = false
        if task.data then
            
            local queryParamsStr = HttpService:JSONEncode(task.data)
            log("flushQueue 订单同步数据: " .. tostring(queryParamsStr))
            local response = request({
                Url = url,
                Method = "POST",
                Headers = {
                    ["Content-Type"] = "application/json"
                },
                Body = HttpService:JSONEncode(task.data)
            })
            ok = response.Success
            local logData = {
                message = "flushQueue HTTP请求结果",
                taskId = task.id,
                success = ok,
                responseStatus = response.StatusCode,
                responseBody = response.Body
            }
            
            if task.data and task.data.deliveryOrderId then
                logData.deliveryOrderId = task.data.deliveryOrderId
            else
                logData.orderMainId = task.data.orderMainId
            end
            
            log(HttpService:JSONEncode(logData))

        else
            log(HttpService:JSONEncode({
                message = "flushQueue 任务数据为空",
                taskId = task.id
            }))
        end

        if ok then
            -- 请求成功，从队列中移除
            table.remove(syncState.queue, 1)

            log(HttpService:JSONEncode({
                message = "有序同步成功",
                taskId = task.id,
                recoveryMode = syncState.recoveryMode
            }))

            if task.data and task.deleteFriendInfo and task.deleteFriendInfo.robloxUserId then
                local isDeliveryOrder = task.data.deliveryOrderId ~= nil
                local orderStatus = task.data.orderStatus
                local makeStatus = task.data.makeStatus
                
                -- 统一处理发货订单(makeStatus=2或orderStatus=2)和收货订单(orderStatus=4)的完成状态
                if (isDeliveryOrder and makeStatus == 2) or (not isDeliveryOrder and orderStatus == 4) then
                    log(HttpService:JSONEncode({
                        message = "订单同步成功，开始删除好友",
                        taskId = task.id,
                        robloxUserId = task.deleteFriendInfo.robloxUserId,
                        receiveStatus = task.data.receiveStatus,
                        recoveryMode = syncState.recoveryMode
                    }))
                    
                    -- 检查用户ID是否在例外列表中
                    local shouldDelete = true
                    for _, exemptId in ipairs(EXEMPT_FRIEND_DELETE_USER_IDS) do
                        if task.deleteFriendInfo.robloxUserId == exemptId then
                            shouldDelete = false
                            break
                        end
                    end
                    
                    if shouldDelete then
                        deleteFriend(task.deleteFriendInfo.robloxUserId)
                    end
                end
            end

            -- 如果是订单完成：写入持久完成标记（acks_done）
            if task.data then
                local isDeliveryOrder = task.data.deliveryOrderId ~= nil
                local oid = nil
                
                if isDeliveryOrder then
                    -- 发货订单：检查 makeStatus == 2 和 deliveryOrderId
                    if task.data.makeStatus == 2 and task.data.deliveryOrderId then
                        oid = tostring(task.data.deliveryOrderId)
                    end
                else
                    -- 收货订单：检查 orderStatus == 4 和 orderMainId
                    if task.data.orderStatus == 4 and task.data.orderMainId then
                        oid = tostring(task.data.orderMainId)
                    end
                end
                
                if oid then
                    syncState.acks_done[oid] = os.time()
                end
            end

            -- 清理过期的完成标记
            local nowTs = os.time()
            -- 新表：acks_done 超过24小时清理
            for k, v in pairs(syncState.acks_done) do
                if nowTs - (v or 0) > 86400 then
                    syncState.acks_done[k] = nil
                end
            end
            
            -- 立即保存状态（移除已完成的记录）
            saveState()
        else
            -- 请求失败，增加重试次数并设置下次重试时间
            task.retry = (task.retry or 0) + 1
            task.nextAttemptAt = now + getRetryInterval(task.retry)

            log(HttpService:JSONEncode({
                message = "有序同步失败，等待重试",
                taskId = task.id,
                retry = task.retry,
                nextAttemptAt = task.nextAttemptAt
            }))

            saveState()
        end
    end)
    
    -- 无论成功还是失败，都要重置处理状态
    syncState.isProcessing = false
    saveState()  -- 立即保存状态重置，防止脚本重启后阻塞
    
    -- 如果出现异常，记录错误
    if not success then
        log(HttpService:JSONEncode({
            message = "flushQueue 处理异常",
            taskId = task.id,
            error = tostring(result)
        }))
    end
end

-- 将HTTP请求添加到可靠队列中
local function guaranteeSync(id, data, deleteFriendInfo)
    -- 判断是否为发货订单
    local isDeliveryOrder = data and data.deliveryOrderId ~= nil
    
    -- 若订单已被确认完成（acks_done），避免重复入队
    if data and syncState.acks_done then
        local oid = nil
        local orderIdField = nil
        
        if isDeliveryOrder then
            -- 发货订单：检查 makeStatus == 2 和 deliveryOrderId
            if data.makeStatus == 2 and data.deliveryOrderId then
                oid = tostring(data.deliveryOrderId)
                orderIdField = "deliveryOrderId"
            end
        else
            -- 收货订单：检查 orderStatus == 4 和 orderMainId
            if data.orderStatus == 4 and data.orderMainId then
                oid = tostring(data.orderMainId)
                orderIdField = "orderMainId"
            end
        end
        
        if oid and syncState.acks_done[oid] then
            log(HttpService:JSONEncode({
                message = "订单已完成(acks_done)，跳过入队",
                [orderIdField] = data[orderIdField],
                taskId = id,
                doneAt = syncState.acks_done[oid]
            }))
            return true
        end
    end

    -- 检查是否已在队列中
    for _, task in ipairs(syncState.queue) do
        if task.id == id then
            local logData = {
                message = "任务已在队列中，跳过重复入队",
                taskId = id
            }
            
            if isDeliveryOrder then
                logData.deliveryOrderId = data and data.deliveryOrderId
            else
                logData.orderMainId = data and data.orderMainId
            end
            
            log(HttpService:JSONEncode(logData))
            return true
        end
    end

    -- 添加到队列
    table.insert(syncState.queue, {
        id = id,
        data = data,  -- POST请求的数据
        deleteFriendInfo = deleteFriendInfo,  -- 删除好友信息
        retry = 0,
        nextAttemptAt = 0,
        createdAt = os.time()
    })
    local logData = {
        message = "任务已入队，准备同步",
        taskId = id,
        queueSize = #syncState.queue
    }
    
    if isDeliveryOrder then
        logData.deliveryOrderId = data and data.deliveryOrderId
    else
        logData.orderMainId = data and data.orderMainId
    end
    
    log(HttpService:JSONEncode(logData))


    saveState()  -- 保存状态
    flushQueue() -- 立即尝试发送
    return true
end

-- ================= 前端故障恢复 =================

-- 保存进行中的订单信息
local function saveActiveOrder(orderId, orderData, isDelivery)
    local isDeliveryOrder = isDelivery == true
    
    syncState.activeOrder = {
        user = orderData.user,
        initialInventory = orderData.initialInventory,
        totalReceived = orderData.totalReceived,
        startTime = orderData.startTime,
        lastUpdateTime = os.time(),
        receiveStatus = orderData.receiveStatus or 0
    }
    
    if isDeliveryOrder then
        syncState.activeOrder.deliveryOrderId = orderId
        syncState.activeOrder.items = orderData.items
        syncState.activeOrder.makeStatus = orderData.makeStatus
    else
        syncState.activeOrder.orderMainId = orderId
        syncState.activeOrder.orderList = orderData.orderList
        syncState.activeOrder.orderStatus = orderData.orderStatus
    end
    
    saveState()
end

-- 移除已完成的订单
local function removeActiveOrder(orderId)
    if syncState.activeOrder and (syncState.activeOrder.orderMainId == orderId or syncState.activeOrder.deliveryOrderId == orderId) then
        syncState.activeOrder = nil
        saveState()
    end
end

-- 更新订单进度
local function updateActiveOrderProgress(orderId, totalReceived,robloxUserId, receiveStatus)
    if syncState.activeOrder and (syncState.activeOrder.orderMainId == orderId or syncState.activeOrder.deliveryOrderId == orderId) then
        syncState.activeOrder.totalReceived = totalReceived
        syncState.activeOrder.robloxUserId = robloxUserId
        syncState.activeOrder.lastUpdateTime = os.time()
        if receiveStatus ~= nil then
            syncState.activeOrder.receiveStatus = receiveStatus
        end
        saveState()
    end
end


-- 检查并恢复进行中的订单（最多1个）
local function checkAndRecoverActiveOrders()
    if syncState.activeOrder then
        local now = os.time()
        syncState.activeOrder.lastUpdateTime = now
        local isDeliveryOrder = syncState.activeOrder.deliveryOrderId ~= nil
        
        -- 构建日志数据
        local logData = {
            message = "发现可恢复的进行中订单",
            user = syncState.activeOrder.user,
            totalReceived = syncState.activeOrder.totalReceived,
            lastUpdateTime = syncState.activeOrder.lastUpdateTime
        }
        
        if isDeliveryOrder then
            logData.deliveryOrderId = syncState.activeOrder.deliveryOrderId
        else
            logData.orderMainId = syncState.activeOrder.orderMainId
        end
        
        log(HttpService:JSONEncode(logData))
        return syncState.activeOrder
    end
    
    return nil
end

-- 恢复订单并同步已收到的物品
local function recoverOrderAndSync(orderData)
    local isDeliveryOrder = orderData.deliveryOrderId ~= nil
    local orderId = isDeliveryOrder and orderData.deliveryOrderId or orderData.orderMainId
    local orderType = isDeliveryOrder and "deliveryOrderId" or "orderMainId"
    local user = orderData.user
    local totalReceived = orderData.totalReceived

    -- 统一的日志记录
    log(HttpService:JSONEncode({
        message = "恢复订单并同步已收到物品",
        [orderType] = orderId,
        user = user,
        totalReceived = totalReceived
    }), {
        log_type = "trade_error",
        [orderType] = orderId,
        orderStatus = isDeliveryOrder and nil or orderData.orderStatus,
        makeStatus = isDeliveryOrder and orderData.makeStatus or nil,
    })

    -- 构建查询参数
    local queryParams = {
        authSecret = authSecret
    }
    
    -- 根据订单类型设置ID字段和状态字段
    if isDeliveryOrder then
        queryParams.deliveryOrderId = orderId
        queryParams.makeStatus = orderData.makeStatus
    else
        queryParams.orderMainId = orderId
        queryParams.orderStatus = orderData.orderStatus
    end

    -- 添加订单列表数据
    if isDeliveryOrder then
        -- 发货订单：根据库存快照计算当前已发出进度，并直接以错误结束（makeStatus=2, receiveStatus=4）
        local invSnapshot = select(1, organizePetsInBackpack())
        local totalDelivered = {}
        if type(orderData.items) == "table" then
            for _, it in ipairs(orderData.items) do
                local itemId = it.tradeId
                local targetQuantity = it.orderQuantity
                local initialCount = (orderData.initialInventory and orderData.initialInventory[itemId]) or 0
                local currentCount = getItemNumFromSnapshot(invSnapshot, itemId)
                local delivered = math.max(0, initialCount - currentCount)
                totalDelivered[itemId] = {
                    orderId = it.deliveryOrderItemId,
                    quantity = math.min(delivered, targetQuantity),
                    deliveryOrderItemId = it.deliveryOrderItemId
                }
            end
        end
        queryParams.items = buildDeliveryItemsFromTotalDelivered(totalDelivered, 2, 4)
        queryParams.makeStatus = 2
        queryParams.receiveStatus = 4
    else
        -- 收货订单使用orderList字段（仅在有进度数据时）
        if totalReceived then
            queryParams.orderList = buildOrderListFromTotalReceived(totalReceived, orderData.orderStatus, orderData.receiveStatus)
        end
    end

    -- 生成同步ID
    local syncId = tostring(orderId) .. ":recovery"
    
    -- 如果是订单结束，传递删除好友信息
    local deleteFriendInfo = nil
    if ((isDeliveryOrder and queryParams.makeStatus == 2) or (not isDeliveryOrder and queryParams.orderStatus == 4)) and orderData.robloxUserId then
        deleteFriendInfo = {
            robloxUserId = orderData.robloxUserId
        }
    end

    guaranteeSync(syncId, queryParams, deleteFriendInfo)

    -- 若恢复时已判断完成或收货完成，立即移除活跃订单
    if (isDeliveryOrder and queryParams.makeStatus == 2) or (not isDeliveryOrder and queryParams.orderStatus == 4) then
        removeActiveOrder(orderId)
    end
end


-- 初始化状态
syncState = loadState()

-- 系统启动时的故障恢复检查
task.spawn(function()
    log(HttpService:JSONEncode({
        message = "开始系统启动时的故障恢复检查"
    }))

    -- 检查并恢复进行中的订单（最多1个）
    local orderToRecover = checkAndRecoverActiveOrders()

    if orderToRecover then
        local isDeliveryOrder = orderToRecover.deliveryOrderId ~= nil
        local orderId = isDeliveryOrder and orderToRecover.deliveryOrderId or orderToRecover.orderMainId
        local orderType = isDeliveryOrder and "deliveryOrderId" or "orderMainId"
        
        log(HttpService:JSONEncode({
            message = "发现需要恢复的订单",
            [orderType] = orderId,
            user = orderToRecover.user
        }))
    
        -- 恢复订单并同步已收到的物品
        recoverOrderAndSync(orderToRecover)
        
        log(HttpService:JSONEncode({
            message = "故障恢复检查完成",
            [orderType] = orderId
        }))

    else
        log(HttpService:JSONEncode({
            message = "未发现需要恢复的订单"
        }))
    end
end)

-- 系统启动时自动移动到1号农场
task.spawn(function()
    log(HttpService:JSONEncode({
        message = "检测到房主，准备移动到1号农场"
    }))
    moveToFarm1()
    for _, player in pairs(Players:GetPlayers()) do
    log(HttpService:JSONEncode({
        message = "玩家列表",
        playerName = player.Name,
        playerId = player.UserId
        }))
    end
end)

-- 后台处理循环
task.spawn(function()
    while true do
        flushQueue()

        -- 强制处理机制：如果队列不为空且长时间未处理，强制重置状态
        if #syncState.queue > 0 and syncState.isProcessing then
            local now = os.time()
            if syncState.lastProcessTime > 0 and (now - syncState.lastProcessTime) > 120 then -- 2分钟强制重置
                log(HttpService:JSONEncode({
                    message = "强制重置处理状态，队列可能被阻塞",
                    queueSize = #syncState.queue,
                    lastProcessTime = syncState.lastProcessTime,
                    timeSinceLastProcess = now - syncState.lastProcessTime
                }))
                syncState.isProcessing = false
                saveState()
            end
        end

        -- 动态调整等待时间
        local waitTime = SYNC_CONFIG.checkInterval

        if syncState.recoveryMode then
            waitTime = 2                                               -- 恢复模式：2秒
        elseif not syncState.serverHealthy then
            waitTime = math.min(30, 5 * syncState.consecutiveFailures) -- 故障模式：最长30秒
        end

        task.wait(waitTime)
    end
end)

-- ================ 原订单回调：改为入队保证送达 ================
local function reportOrder(data)
    local orderStatus, receiveStatus, orderMainId = data.orderStatus, data.receiveStatus, data.orderMainId
    local makeStatus = data.makeStatus  -- 发货订单使用makeStatus
    -- orderStatus 1 发货开始 2发货结束 (收货订单: 2开始 4结束)
    -- receiveStatus 1 成功 2 卖家未进私服 3 交易超时/不匹配/未确认 4 其它错误（程序异常/恢复模式上报）
    
    -- 判断是否为发货订单（通过检查是否有deliveryOrderId字段）
    local isDeliveryOrder = data.deliveryOrderId ~= nil
    
    -- 构建POST请求数据
    local queryParams = {
        authSecret = authSecret
    }
    
    -- 如果是发货订单，使用发货订单的字段名
    if isDeliveryOrder then
        queryParams.deliveryOrderId = data.deliveryOrderId
        -- 发货订单使用makeStatus字段
        queryParams.makeStatus = makeStatus or orderStatus
    else
        -- 收货订单使用原有字段：orderStatus 2(开始收货), 4(收货完成)
        queryParams.orderMainId = orderMainId
        queryParams.orderStatus = orderStatus
    end
    
    if orderStatus == 4 then
        -- queryParams.receiveStatus = receiveStatus
    end
    
    if data.totalReceived then
        queryParams.orderList = buildOrderListFromTotalReceived(data.totalReceived, orderStatus, receiveStatus)
    end
    
    -- 如果是发货订单且有totalDelivered数据，转换为发货订单格式
    if isDeliveryOrder and data.totalDelivered then
        queryParams.items = buildDeliveryItemsFromTotalDelivered(data.totalDelivered, orderStatus, receiveStatus)
    end
    
    local queryParamsStr = HttpService:JSONEncode(queryParams)
    log("回调 queryParamsStr: " .. tostring(queryParamsStr))

    if runTag ~= 0 then
        -- 将同步任务写入本地可靠队列，后台会自动重试直到成功
        -- 根据订单类型生成唯一任务ID：
        -- 收货：orderMainId:orderStatus:receiveStatus
        -- 发货：deliveryOrderId:makeStatus:receiveStatus
        local gid
        if isDeliveryOrder then
            gid = tostring(data.deliveryOrderId) .. ":" .. tostring(makeStatus or 0) .. ":" .. tostring(receiveStatus or 0)
        else
            gid = tostring(orderMainId) .. ":" .. tostring(orderStatus) .. ":" .. tostring(receiveStatus or 0)
        end
        
        -- 如果是订单结束，传递删除好友信息
        local deleteFriendInfo = nil
        if (isDeliveryOrder and (makeStatus == 2)) or (not isDeliveryOrder and orderStatus == 4) then
            if data.robloxUserId then
                deleteFriendInfo = {
                    robloxUserId = data.robloxUserId
                }
            end
        end        

        guaranteeSync(gid, queryParams, deleteFriendInfo)
    end
end

-- 核心：收货流程 - 支持多个物品
local function runReceiving(mainOrderData)
    local success, response = pcall(function()
        local user = mainOrderData.robloxUserName
        local orderMainId = mainOrderData.orderMainId
        local orderList = mainOrderData.orderList

        -- 记录初始库存数量
        local initialInventory = {}
        for _, order in ipairs(orderList) do
            local itemId = order.product.tradeId
            initialInventory[itemId] = getItemNum(itemId)
        end

        -- 回调"订单开始"
        local reportData = {
            orderMainId = orderMainId,
            orderStatus = 2
        }
        log(HttpService:JSONEncode({
            message = "收货开始交易",
            orderMainId = orderMainId,
            user = user,
            orderList = orderList,
            initialInventory = initialInventory
        }), {
            log_type = "trade_start",
            orderMainId = orderMainId,
            orderStatus = reportData.orderStatus
        })
        -- say("收货开始交易")
        sendTradeHint(6)
        reportOrder(reportData)
        
        -- 找到目标玩家并靠近
        local target = getTarget(user)
        if not target then
            log(HttpService:JSONEncode({
                message = "无法找到目标玩家",
                orderMainId = orderMainId,
                user = user,
                totalReceived = totalReceived,
                reason = reason
            }), {
                log_type = "trade_error",
                orderMainId = orderMainId,
                orderStatus = 4,
                receiveStatus = 2
            })

            -- 回调用户掉线状态
            reportData.orderStatus = 4
            reportData.receiveStatus = 2
            reportData.totalReceived = totalReceived
            reportData.robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
            reportOrder(reportData)

            -- 结束后返回农场1
            moveToFarm1()

            return
        end
        
        log(HttpService:JSONEncode({
            message = "找到目标玩家，开始靠近",
            orderMainId = orderMainId,
            user = user,
            targetName = target.Name
        }))
        
        -- 移动到目标玩家附近
        if not moveNear(target, 10) then
            log(HttpService:JSONEncode({
                message = "无法靠近目标玩家",
                orderMainId = orderMainId,
                user = user,
                targetName = target.Name
            }))
        end
        
        log(HttpService:JSONEncode({
            message = "已成功靠近目标玩家",
            orderMainId = orderMainId,
            user = user,
            targetName = target.Name
        }))
        
        -- 开始多轮交易，直到所有物品都收到
        local totalReceived = {}
        -- 初始化 totalReceived，包含 orderProductId 信息
        for _, order in ipairs(orderList) do
            local itemId = order.product.tradeId
            local orderProductId = order.product.orderProductId
            totalReceived[itemId] = {
                orderId = order.orderId,
                quantity = 0,
                orderProductId = orderProductId
            }
        end
        local startTime = os.time()
        local tradeRequestStartTime = os.time() -- 交易请求开始时间

        -- 保存进行中的订单信息到持久化存储
        local orderData = {
            user = user,
            orderList = orderList,
            initialInventory = initialInventory,
            totalReceived = totalReceived,
            startTime = startTime,
            orderStatus = reportData.orderStatus
        }
        saveActiveOrder(orderMainId, orderData, false)

        -- ================== 设置自动接受礼物监听器 ==================
        local autoAcceptLoopConnection = nil
        -- 收货订单完成标记
        local allCompleted = false       

        -- 检查并更新收到宠物的函数
        local function updateReceivedPet(orderDetail, context)
            if not orderDetail or not orderDetail.tradeId then
                log(HttpService:JSONEncode({
                    message = (context or "") .. "警告：无法获取订单详情或订单详情为空",
                    orderDetail = orderDetail
                }))
                return
            end
            
            local itemId = orderDetail.tradeId

            -- 更新已收到的宠物数量
            totalReceived[itemId].quantity = totalReceived[itemId].quantity + 1
            log(HttpService:JSONEncode({
                message = (context or "") .. "更新收到宠物数据",
                itemId = itemId,
                newQuantity = totalReceived[itemId].quantity,
                orderId = orderDetail.orderId
            }))
            
            -- 更新持久化存储中的订单进度
            updateActiveOrderProgress(orderMainId, totalReceived, mainOrderData.robloxUserId, reportData.receiveStatus)
            
            -- 检查是否所有宠物都已收到
            local allItemsCompleted = true
            for _, order in ipairs(orderList) do
                local targetItemId = order.product.tradeId
                local targetQuantity = order.product.quantity
                if not totalReceived[targetItemId] or totalReceived[targetItemId].quantity < targetQuantity then
                    allItemsCompleted = false
                    break
                end
            end
            
            if allItemsCompleted then
                allCompleted = true
                log(HttpService:JSONEncode({
                    message = (context or "") .. "所有宠物都已收到，标记订单完成",
                    orderMainId = orderMainId,
                    user = user,
                    totalReceived = totalReceived
                }))
            end
        end

        -- 设置自动接受礼物的监听器
        local function setupAutoAcceptForReceiving()
            -- 等待并获取玩家GUI
            local pg = LocalPlayer:WaitForChild("PlayerGui")
            
            -- 后台循环机制
            autoAcceptLoopConnection = task.spawn(function()
                while true do
                    -- 检查是否超时
                    if os.time() - startTime > maxTradeTime then
                        log(HttpService:JSONEncode({
                            message = "收货交易超时",
                            orderMainId = orderMainId,
                            user = user,
                            totalReceived = totalReceived
                        }), {
                            log_type = "trade_error",
                            orderMainId = orderMainId,
                            orderStatus = 4,
                            receiveStatus = 3
                        })

                        -- 回调超时状态
                        reportData.orderStatus = 4
                        reportData.receiveStatus = 3
                        reportData.totalReceived = totalReceived
                        reportData.robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
                        reportOrder(reportData)
                        -- 提示5：超过10分钟仍未完成
                        sendTradeHint(5)
                        -- 移除已完成的订单，避免重复处理
                        removeActiveOrder(orderMainId)
                        -- 超时结束后返回农场1
                        moveToFarm1()
                        break
                    end

                    -- 检查是否存在礼物通知界面
                    local giftNotification = pg:FindFirstChild("Gift_Notification")
                    if giftNotification then
                        -- 仅在收到且显示可点击的接受按钮时才处理（视为已收到交易/礼物请求）
                        local acceptBtn = select(1, getButtons())
                        if acceptBtn and acceptBtn.Visible == true then
                            log(HttpService:JSONEncode({
                                message = "后台循环检测到礼物通知界面，开始处理",
                                orderMainId = orderMainId,
                                user = user
                            }))
                            
                            -- 检查目标玩家手中的宠物是否符合要求
                            local isValidPet, orderDetail = checkTargetPlayerPet(user, orderList) -- 默认检查Bunny宠物
                            
                            if isValidPet then
								-- 数量上限检查：若该物品已达到/超过订单数量，则拒绝
								local itemId = orderDetail and orderDetail.tradeId
								local targetQuantity = (orderDetail and orderDetail.order and orderDetail.order.product and orderDetail.order.product.quantity) or (orderDetail and orderDetail.quantity) or 0
								local receivedSoFar = (itemId and totalReceived[itemId] and totalReceived[itemId].quantity) or 0
								if receivedSoFar >= targetQuantity then
									log(HttpService:JSONEncode({
										message = "后台循环：该物品已达订单数量上限，拒绝接受礼物",
										orderMainId = orderMainId,
										user = user,
										itemId = itemId,
										received = receivedSoFar,
										target = targetQuantity
									}))
									autoDecline()
									sendTradeHint(3)
								else
									log(HttpService:JSONEncode({
										message = "后台循环：目标玩家手中的宠物符合要求，准备接受礼物",
										orderMainId = orderMainId,
										user = user,
										orderDetail = orderDetail
									}))
									autoAccept()
									
									-- 更新收到的宠物数据
									updateReceivedPet(orderDetail, "后台循环：")
								end
                            else
                                log(HttpService:JSONEncode({
                                    message = "后台循环：目标玩家手中的宠物不符合要求，拒绝接受礼物",
                                    orderMainId = orderMainId,
                                    user = user,
                                }))
                                autoDecline()
                                sendTradeHint(2)
                                
                            end
                        end
                    end
                    
                    task.wait(1) -- 每秒检查一次
                    
                    if allCompleted then
                        log(HttpService:JSONEncode({
                            message = "收货交易完成",
                            orderMainId = orderMainId,
                            user = user,
                            totalReceived = totalReceived
                        }), {
                            log_type = "trade_success",
                            orderMainId = orderMainId,
                            orderStatus = 4
                        })

                        -- 移除已完成的订单
                        removeActiveOrder(orderMainId)

                        -- 回调成功状态
                        reportData.orderStatus = 4
                        reportData.receiveStatus = 1
                        reportData.totalReceived = totalReceived
                        reportData.robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
                        reportOrder(reportData)
                        -- 完成后返回农场1
                        moveToFarm1()
                        break
                    end

                    -- 检查用户是否仍然在线且已准备就绪
                    local isReady, reason = isUserOnlineAndReady(user)
                    if not isReady then
                        log(HttpService:JSONEncode({
                            message = "收货用户状态异常: " .. reason,
                            orderMainId = orderMainId,
                            user = user,
                            totalReceived = totalReceived,
                            reason = reason
                        }), {
                            log_type = "trade_error",
                            orderMainId = orderMainId,
                            orderStatus = 4,
                            receiveStatus = 2
                        })

                        -- 回调用户掉线状态
                        reportData.orderStatus = 4
                        reportData.receiveStatus = 2
                        reportData.totalReceived = totalReceived
                        reportData.robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
                        reportOrder(reportData)

                        -- 保留订单信息用于故障恢复，不删除
                        -- 结束后返回农场1
                        moveToFarm1()
                        break
                    end

                end
            end)
        end
        
        -- 启动自动接受监听器
        setupAutoAcceptForReceiving()
    end)

    if not success then
        log("runReceiving err:" .. tostring(response))
        local reportData = {
            orderMainId = mainOrderData.orderMainId,
            orderStatus = 4,
            receiveStatus = 4, -- 程序异常
            robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
        }
        reportOrder(reportData)
        
        
        -- 清理监听器（只清理后台循环）
        if autoAcceptLoopConnection then
            task.cancel(autoAcceptLoopConnection)
            autoAcceptLoopConnection = nil
        end
    end
end

-- 核心：发货流程 - 支持多个物品
local function runDelivery(mainOrderData)
    local success, response = pcall(function()
        local user = mainOrderData.robloxUserName
        local deliveryOrderId = mainOrderData.deliveryOrderId 
        local items = mainOrderData.items
        
        -- 检查订单是否正在处理中（使用 syncState.activeOrder）
        if syncState.activeOrder and syncState.activeOrder.deliveryOrderId == deliveryOrderId then
            log(HttpService:JSONEncode({
                message = "发货订单正在处理中，跳过重复处理",
                deliveryOrderId = deliveryOrderId,
                user = user
            }))
            return
        end

        -- 记录初始库存数量
        local initialInventory = {}
        for _, order in ipairs(items) do
            local itemId = order.tradeId 
            initialInventory[itemId] = getItemNum(itemId)
        end

        -- 先保存进行中的订单信息（用于故障恢复与去重），再打印“发货开始交易”
        local reportData = {
            deliveryOrderId = deliveryOrderId,  -- 发货订单使用deliveryOrderId
            makeStatus = 1
        }
        local orderData = {
            deliveryOrderId = deliveryOrderId,
            user = user,
            items = items,
            initialInventory = initialInventory,
            startTime = os.time(),
            makeStatus = reportData.makeStatus
        }
        saveActiveOrder(deliveryOrderId, orderData, true)

        -- 回调"订单开始"（只应打印一次；activeOrder已设置可防重复）
        log(HttpService:JSONEncode({
            message = "发货开始交易",
            deliveryOrderId = deliveryOrderId,
            user = user,
            items = items,
            initialInventory = initialInventory
        }), {
            log_type = "trade_start",
            deliveryOrderId = deliveryOrderId,
            makeStatus = reportData.makeStatus
        })
        -- say("发货开始交易")
        sendTradeHint(7)
        reportOrder(reportData)

        -- 检查用户是否在线且已准备就绪
        local isReady, reason = isUserOnlineAndReady(user)
        if not isReady then
            log(HttpService:JSONEncode({
                message = "发货用户状态异常: " .. reason,
                deliveryOrderId = deliveryOrderId,
                user = user,
                reason = reason
            }), {
                log_type = "trade_error",
                deliveryOrderId = deliveryOrderId,
                makeStatus = 2,
                receiveStatus = 2
            })

            -- 回调用户掉线状态
            reportData.makeStatus = 2
            reportData.receiveStatus = 2
            reportData.robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
            reportOrder(reportData)
            
            return
        end

        -- 检查所有物品库存是否充足（交易开始前检查初始库存）
        local inventoryCheck = {}
        local allItemsAvailable = true
        for _, order in ipairs(items) do
            local itemId = order.tradeId
            local targetQuantity = order.orderQuantity
            local isPet = isPetName(itemId)
            local currentQuantity = getItemNum(itemId)
            local initialCount = initialInventory[itemId] or 0

            -- 直接检查当前库存是否足够满足订单需求
            local available = currentQuantity >= targetQuantity

            local check = {
                itemId = itemId,
                isPet = isPet,
                targetQuantity = targetQuantity,
                currentQuantity = currentQuantity,
                initialCount = initialCount,
                available = available
            }
            table.insert(inventoryCheck, check)

            if not available then
                allItemsAvailable = false
            end
        end

        if not allItemsAvailable then
            log(HttpService:JSONEncode({
                message = "发货库存不足",
                deliveryOrderId = deliveryOrderId,
                user = user,
                inventoryCheck = inventoryCheck
            }), {
                log_type = "trade_error",
                deliveryOrderId = deliveryOrderId,
                makeStatus = 2,
                receiveStatus = 4
            })

            -- 回调库存不足状态
            reportData.makeStatus = 2
            reportData.receiveStatus = 4
            reportData.robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
            reportOrder(reportData)
            
            -- 移除已完成的订单，避免重复处理
            removeActiveOrder(deliveryOrderId)
            
            -- 不直接return，让系统继续处理其他订单
            log(HttpService:JSONEncode({
                message = "发货库存不足，订单已取消，继续处理其他订单",
                deliveryOrderId = deliveryOrderId,
                user = user
            }))
            say("库存不足，订单已取消")
            -- 结束后返回农场1
            moveToFarm1()
            return
        end


        -- 开始多轮交易，直到所有物品都发出
        local totalDelivered = {}
        -- 初始化 totalDelivered
        for _, order in ipairs(items) do
            local itemId = order.tradeId
            local deliveryOrderItemId = order.deliveryOrderItemId  -- 使用deliveryOrderItemId作为orderProductId
            totalDelivered[itemId] = {
                orderId = order.orderId or order.deliveryOrderItemId,  -- 兼容新旧格式
                quantity = 0,
                deliveryOrderItemId = deliveryOrderItemId
            }
        end
        local startTime = os.time()
        local tradeRequestStartTime = os.time() -- 交易请求开始时间

        while true do
            -- 检查是否超时
            if os.time() - startTime > maxTradeTime then
                log(HttpService:JSONEncode({
                    message = "发货交易超时",
                    deliveryOrderId = deliveryOrderId,
                    user = user,
                    totalDelivered = totalDelivered
                }), {
                    log_type = "trade_error",
                    deliveryOrderId = deliveryOrderId,
                    makeStatus = 2,
                    receiveStatus = 3
                })

                -- 回调超时状态
                reportData.makeStatus = 2
                reportData.receiveStatus = 3
                reportData.totalDelivered = totalDelivered
                reportData.robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
                reportOrder(reportData)
                
                -- 移除已完成的订单，避免重复处理
                removeActiveOrder(deliveryOrderId)
                -- 提示5：超过10分钟仍未完成
                sendTradeHint(5)
                -- 超时结束后返回农场1
                moveToFarm1()
                break
            end


            -- 检查用户是否仍然在线且已准备就绪
            local isReady, reason = isUserOnlineAndReady(user)
            if not isReady then
                log(HttpService:JSONEncode({
                    message = "发货用户状态异常: " .. reason,
                    deliveryOrderId = deliveryOrderId,
                    user = user,
                    totalDelivered = totalDelivered,
                    reason = reason
                }), {
                    log_type = "trade_error",
                    deliveryOrderId = deliveryOrderId,
                    makeStatus = 2,
                    receiveStatus = 2
                })

                -- 回调用户掉线状态
                reportData.makeStatus = 2
                reportData.receiveStatus = 2
                reportData.totalDelivered = totalDelivered
                reportData.robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
                reportOrder(reportData)
                
                
                -- 移除已完成的订单，避免重复处理
                removeActiveOrder(deliveryOrderId)
                -- 结束后返回农场1
                moveToFarm1()
                break
            end

            -- 等待交易状态变化
            local tradeStartTime = os.time()
            local tradeAccepted = false                                     -- 标记交易是否被接受

                    
            -- ================== 赠送宠物逻辑 ==================
            -- 检查订单中是否包含宠物物品
            local hasPetItems = false
            local petItems = {}
            for _, order in ipairs(items) do
                local itemId = order.tradeId
                if isPetName(itemId) then -- 基于名称判断是否为宠物
                    hasPetItems = true
                    table.insert(petItems, order)
                end
            end

            if hasPetItems then
                log(HttpService:JSONEncode({
                    message = "检测到宠物物品，开始赠送宠物流程",
                    deliveryOrderId = deliveryOrderId,
                    user = user,
                    petItems = petItems
                }))

                -- 获取目标玩家
                local target = getTarget(user)
                if not target then 
                    log(HttpService:JSONEncode({
                        message = "无目标玩家",
                        deliveryOrderId = deliveryOrderId,
                        user = user
                    }))
                else
                    log(HttpService:JSONEncode({
                        message = "目标玩家: " .. target.Name,
                        deliveryOrderId = deliveryOrderId,
                        user = user
                    }))
                    
                    -- 处理每个宠物物品（按需求数量循环赠送）
                    for _, petOrder in ipairs(petItems) do
                        local petItemId = petOrder.tradeId
                        local targetQuantity = petOrder.orderQuantity
                        
                        log(HttpService:JSONEncode({
                            message = "开始赠送宠物: " .. petItemId .. " x" .. targetQuantity,
                            deliveryOrderId = deliveryOrderId,
                            user = user
                        }))
                        -- 按剩余数量循环赠送
                        while os.time() - tradeStartTime < singleTradeTimeoutSeconds do
                            -- 计算剩余数量
                            local currentCount = getItemNum(petItemId)
                            local initialCount = initialInventory[petItemId] or 0
                            local deliveredSoFar = math.max(0, initialCount - currentCount)
                            local remaining = math.max(0, targetQuantity - deliveredSoFar)
                            if remaining <= 0 then break end

                            -- 检测背包中是否有指定宠物
                            local pet = findPetInBackpack(petItemId)
                            if not pet then 
                                log(HttpService:JSONEncode({
                                    message = "背包中未找到目标宠物: " .. petItemId,
                                    deliveryOrderId = deliveryOrderId,
                                    user = user
                                }))
                                break
                            end

                            -- 靠近目标
                            if not moveNear(target, 10) then 
                                log(HttpService:JSONEncode({
                                    message = "无法靠近目标",
                                    deliveryOrderId = deliveryOrderId,
                                    user = user
                                }))
                                break
                            end

                            -- 清理/选中
                            clearAllSelections(petItemId)
                            if not selectPet(pet) then 
                                log(HttpService:JSONEncode({
                                    message = "装备宠物失败",
                                    deliveryOrderId = deliveryOrderId,
                                    user = user
                                }))
                                break
                            end
                            task.wait(1.5)

                            -- 触发赠送（E键）
                            local char = target.Character
                            if char and char:FindFirstChild("HumanoidRootPart") then
                                local prompt = char.HumanoidRootPart:FindFirstChildWhichIsA("ProximityPrompt", true)
                                if prompt then
                                    -- 带重试并详细日志的触发
                                    local attempts = 0
                                    local activated = false
                                    while attempts < 5 and not activated do
                                        attempts = attempts + 1
                                        log(HttpService:JSONEncode({ message = "尝试触发赠送提示", attempt = attempts }))
                                        local ok, reason = tryActivatePrompt(prompt, "delivery_gift")
                                        activated = ok == true
                                        if not activated then
                                            log(HttpService:JSONEncode({ message = "触发失败，准备重试", reason = tostring(reason), attempt = attempts }))
                                            task.wait(0.6)
                                        end
                                    end

                                    -- 等待礼物赠送结果
                                    local result = waitForGiftResult(singleTradeTimeoutSeconds)
                                    if result == "completed" then
                                        log("礼物赠送成功: " .. pet.Name)
                                        -- 累计已发出数量
                                        if totalDelivered[petItemId] then
                                            totalDelivered[petItemId].quantity = (totalDelivered[petItemId].quantity or 0) + 1
                                        end
                                        -- 更新持久化订单进度（发货）
                                        updateActiveOrderProgress(deliveryOrderId, totalDelivered, mainOrderData.robloxUserId, nil)
                                        -- 继续循环检查是否还有剩余
                                    elseif result == "declined" then
                                        log("礼物被对方拒绝")
                                        break
                                    elseif result == "timeout" then
                                        log("等待礼物结果超时")
                                        break
                                    elseif result == "failed" then
                                        log("礼物赠送失败")
                                        break
                                    elseif result == "error" then
                                        log("礼物结果检测出错")
                                        break
                                    end
                                else
                                    log(HttpService:JSONEncode({
                                        message = "目标玩家身上未找到 ProximityPrompt",
                                        deliveryOrderId = deliveryOrderId,
                                        user = user
                                    }))
                                    break
                                end
                            else
                                log(HttpService:JSONEncode({
                                    message = "目标玩家角色或 HumanoidRootPart 不存在",
                                    deliveryOrderId = deliveryOrderId,
                                    user = user
                                }))
                                break
                            end

                            task.wait(0.5)
                        end
                    end

                    -- 检查是否所有物品都已发出（单次批量拉取库存快照，避免多次RPC）
                    local success, invSnapshot = pcall(function()
                        return organizePetsInBackpack()
                    end)
                    
                    if not success then
                        -- 如果获取库存快照失败，记录错误并继续
                        log("获取库存快照失败: " .. tostring(invSnapshot))
                        invSnapshot = {}
                    end
                    
                    local allCompleted = true
                    local progressInfo = {}

                    for _, order in ipairs(items) do
                        local itemId = order.tradeId 
                        local targetQuantity = order.orderQuantity
                        local currentQuantity = getItemNumFromSnapshot(invSnapshot, itemId)
                        local deliveredQuantity = totalDelivered[itemId] and totalDelivered[itemId].quantity or 0
                        local initialCount = initialInventory[itemId] or 0
                        local actualDelivered = math.max(0, initialCount - currentQuantity)

                        local progress = {
                            itemId = itemId,                                          -- 物品ID
                            targetQuantity = targetQuantity,                          -- 目标数量
                            currentQuantity = currentQuantity,                        -- 当前库存数量
                            deliveredQuantity = deliveredQuantity,                    -- 已发出数量
                            actualDelivered = actualDelivered,                        -- 实际发出数量
                            remaining = math.max(0, targetQuantity - actualDelivered) -- 剩余需要数量
                        }

                        table.insert(progressInfo, progress)
                        if actualDelivered < targetQuantity then
                            allCompleted = false
                        end
                    end

                    -- 每轮检查都记录进度
                    if not allCompleted then
                        log(HttpService:JSONEncode({
                            message = "发货交易进度",
                            deliveryOrderId = deliveryOrderId,
                            user = user,
                            progress = progressInfo,
                            totalDelivered = totalDelivered
                        }), {
                            log_type = "progress",
                            deliveryOrderId = deliveryOrderId,
                            makeStatus = reportData.makeStatus
                        })
                    end

                    if allCompleted then
                        log(HttpService:JSONEncode({
                            message = "发货交易完成",
                            deliveryOrderId = deliveryOrderId,
                            user = user,
                            totalDelivered = totalDelivered
                        }), {
                            log_type = "trade_success",
                            deliveryOrderId = deliveryOrderId,
                            makeStatus = 2
                        })

                        -- 回调成功状态
                        reportData.makeStatus = 2
                        reportData.receiveStatus = 1
                        reportData.totalDelivered = totalDelivered
                        reportData.robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
                        reportOrder(reportData)
                        
                        -- 移除已完成的订单，避免重复处理
                        removeActiveOrder(deliveryOrderId)
                        -- 完成后返回农场1
                        moveToFarm1()
                        break
                    end

                end
            end


            -- 交易被接受，重置交易请求开始时间
            tradeRequestStartTime = os.time()
        

            -- 交易完成后等待一段时间再发起下一轮
            task.wait(tradeInterval)
        end
    end)

    if not success then
        log("runDelivery err:" .. tostring(response))
        local reportData = {
            deliveryOrderId = mainOrderData.deliveryOrderId,
            makeStatus = 2,
            receiveStatus = 4, -- 程序异常
            robloxUserId = mainOrderData.robloxUserId  -- 传递删除好友所需的用户ID
        }
        reportOrder(reportData)
        
        -- 移除异常的订单，避免重复处理
        removeActiveOrder(mainOrderData.deliveryOrderId)
    end
end

local function run()
    while true do
        -- 若存在进行中的订单，则不拉取新订单，等待当前订单完成
        if syncState.activeOrder then
            task.wait(postOrderWaitSeconds)
        else
            -- 同时获取收货和发货订单
            local ReceivingData = getReceivingOrder()
            local DeliveryData = getDeliveryOrder()
            
            -- 检查是否有订单数据
            local hasReceiving = ReceivingData and ReceivingData.orderMainId
            local hasDelivery = DeliveryData and DeliveryData.deliveryOrderId
        
            if hasReceiving or hasDelivery then
                -- 如果两个订单都存在，根据createTime决定先处理哪个
                local shouldProcessReceiving = false
                local shouldProcessDelivery = false
                
                if hasReceiving and hasDelivery then
                    -- 比较createTime，时间小的先处理
                    local receivingTime = ReceivingData.createTime or 0
                    local deliveryTime = DeliveryData.createTime or 0
                    
                    local logData = {
                        receivingTime = receivingTime,
                        deliveryTime = deliveryTime
                    }
                    
                    if receivingTime <= deliveryTime then
                        shouldProcessReceiving = true
                        logData.message = "收货订单时间更早，先处理收货"
                        logData.receivingOrderId = ReceivingData.orderMainId
                        logData.deliveryOrderId = DeliveryData.deliveryOrderId
                    else
                        shouldProcessDelivery = true
                        logData.message = "发货订单时间更早，先处理发货"
                        logData.deliveryOrderId = DeliveryData.deliveryOrderId
                        logData.receivingOrderId = ReceivingData.orderMainId
                    end
                    
                    -- log(HttpService:JSONEncode(logData))

                    
                elseif hasReceiving then
                    shouldProcessReceiving = true
                elseif hasDelivery then
                    shouldProcessDelivery = true
                end
                
                -- 处理收货订单
                if shouldProcessReceiving then
                    -- 先判断玩家是否在线且在同一房间；不在线则最多等待10分钟，期间轮询
                    local user = ReceivingData.robloxUserName
                    local onlineWaitStart = os.time()
                    local isInRoom, reason = isUserInSameRoom(user)
                    local didWaitForOnline = false
                    local hasLoggedWait = false -- 只打印一次等待日志
                    while not isInRoom and (os.time() - onlineWaitStart) < waitTradeTime do
                        task.wait(5)
                        isInRoom, reason = isUserInSameRoom(user)
                        didWaitForOnline = true

                            if not hasLoggedWait then
                                hasLoggedWait = true
                                log(HttpService:JSONEncode({
                                    message = "等待收货玩家上线: " .. tostring(reason),
                                    user = user,
                                    waited = tostring(os.time() - onlineWaitStart),
                                    reason = reason
                                }))
                            end
                        end

                        if isInRoom then
                            if didWaitForOnline then
                                -- 刚从离线转为在线：等待玩家完全加载后再开始收货交易
                                log(HttpService:JSONEncode({
                                    message = "收货玩家刚上线，等待完全加载后发起交易",
                                    user = user,
                                    orderMainId = ReceivingData.orderMainId
                                }))

                                -- 等待玩家完全加载（最多等待30秒）
                                local isReady, reason = waitForUserReady(user, 30)
                                if not isReady then
                                    log(HttpService:JSONEncode({
                                        message = "等待玩家加载超时: " .. reason,
                                        user = user,
                                        orderMainId = ReceivingData.orderMainId
                                    }), { log_type = "trade_error", orderMainId = ReceivingData.orderMainId, orderStatus = 2 })
                                else
                                    -- 额外缓冲30秒确保玩家完全稳定
                                    task.wait(30)
                                    runReceiving(ReceivingData)
                                end
                            else
                                -- 一开始就在线：确保玩家已准备就绪后直接发起交易
                                local isReady, reason = isUserOnlineAndReady(user)
                                if not isReady then
                                    log(HttpService:JSONEncode({
                                        message = "玩家未准备就绪: " .. reason,
                                        user = user,
                                        orderMainId = ReceivingData.orderMainId
                                    }), { log_type = "trade_error", orderMainId = ReceivingData.orderMainId, orderStatus = 2 })
                                else
                                    log(HttpService:JSONEncode({
                                        message = "收货玩家已准备就绪，立即发起交易",
                                        user = user,
                                        orderMainId = ReceivingData.orderMainId
                                    }))
                                    -- 玩家一直在线，交易系统应该已经就绪，直接发起交易
                                    runReceiving(ReceivingData)
                                end
                            end
                        else
                            local reportData = {
                                orderMainId = ReceivingData.orderMainId,
                                orderStatus = 2  -- 收货开始
                            }
                            reportOrder(reportData)

                            -- 超时仍未上线，回调 receiveStatus=2
                            log(HttpService:JSONEncode({
                                message = "收货玩家长时间不在线，跳过本轮订单",
                                user = user,
                                orderMainId = ReceivingData.orderMainId
                            }), {
                                log_type = "trade_error",
                                orderMainId = ReceivingData.orderMainId,
                                orderStatus = 4
                            })

                            reportOrder({
                                orderMainId = ReceivingData.orderMainId,
                                orderStatus = 4,
                                receiveStatus = 2,
                                robloxUserId = ReceivingData.robloxUserId  -- 传递删除好友所需的用户ID
                            })
                        end
                end
                
                -- 处理发货订单
                if shouldProcessDelivery then
                    -- 先判断玩家是否在线且在同一房间；不在线则最多等待10分钟，期间轮询
                    local user = DeliveryData.robloxUserName
                    local onlineWaitStart = os.time()
                    local isInRoom, reason = isUserInSameRoom(user)
                    local didWaitForOnline = false
                    local hasLoggedWait = false -- 只打印一次等待日志
                    while not isInRoom and (os.time() - onlineWaitStart) < waitTradeTime do
                        task.wait(5)

                            isInRoom, reason = isUserInSameRoom(user)
                            didWaitForOnline = true

                            if not hasLoggedWait then
                                hasLoggedWait = true
                                log(HttpService:JSONEncode({
                                    message = "等待发货玩家上线: " .. tostring(reason),
                                    user = user,
                                    waited = tostring(os.time() - onlineWaitStart),
                                    reason = reason
                                }))
                            end
                        end

                        if isInRoom then
                            if didWaitForOnline then
                                -- 刚从离线转为在线：等待玩家完全加载后再开始发货交易
                                log(HttpService:JSONEncode({
                                    message = "发货玩家刚上线，等待完全加载后发起交易",
                                    user = user,
                                    deliveryOrderId = DeliveryData.deliveryOrderId
                                }))

                                -- 等待玩家完全加载（最多等待30秒）
                                local isReady, reason = waitForUserReady(user, 30)
                                if not isReady then
                                    log(HttpService:JSONEncode({
                                        message = "等待玩家加载超时: " .. reason,
                                        user = user,
                                        deliveryOrderId = DeliveryData.deliveryOrderId
                                    }), { log_type = "trade_error", deliveryOrderId = DeliveryData.deliveryOrderId, makeStatus = 2 })
                                else
                                    -- 额外缓冲30秒确保玩家完全稳定
                                    task.wait(30)
                                    runDelivery(DeliveryData)
                                end
                            else
                                -- 一开始就在线：确保玩家已准备就绪后直接发起交易
                                local isReady, reason = isUserOnlineAndReady(user)
                                if not isReady then
                                    log(HttpService:JSONEncode({
                                        message = "玩家未准备就绪: " .. reason,
                                        user = user,
                                        deliveryOrderId = DeliveryData.deliveryOrderId
                                    }), { log_type = "trade_error", deliveryOrderId = DeliveryData.deliveryOrderId, makeStatus = 2 })
                                else
                                    log(HttpService:JSONEncode({
                                        message = "发货玩家已准备就绪，立即发起交易",
                                        user = user,
                                        deliveryOrderId = DeliveryData.deliveryOrderId
                                    }))
                                    -- 玩家一直在线，交易系统应该已经就绪，直接发起交易
                                    runDelivery(DeliveryData)
                                end
                            end
                        else
                            
                            local reportData = {
                                deliveryOrderId = DeliveryData.deliveryOrderId,
                                makeStatus = 1  -- 发货开始
                            }
                            reportOrder(reportData)
                            -- 超时仍未上线，回调 receiveStatus=2
                            log(HttpService:JSONEncode({
                                message = "发货玩家长时间不在线，跳过本轮订单",
                                user = user,
                                deliveryOrderId = DeliveryData.deliveryOrderId
                            }), {
                                log_type = "trade_error",
                                deliveryOrderId = DeliveryData.deliveryOrderId,
                                makeStatus = 2
                            })

                            reportOrder({
                                deliveryOrderId = DeliveryData.deliveryOrderId,
                                makeStatus = 2,
                                receiveStatus = 2,
                                robloxUserId = DeliveryData.robloxUserId  -- 传递删除好友所需的用户ID
                            })
                        end
                end
            else
                -- 没有订单时，短暂等待后继续循环
                task.wait(postOrderWaitSeconds)
            end
        end 
    end
end

task.spawn(run)
